pandas で文字列データを扱うとき、str アクセサを使うと列全体に文字列メソッドを一括適用できます。ループを書かずに済むので、コードが簡潔になり、処理も高速です。
基本的な使い方
df['列名'].str.メソッド名() の形式で、文字列メソッドを適用します。
import pandas as pd
df = pd.DataFrame({
'name': ['Alice Smith', 'Bob Jones', 'Charlie Brown']
})
# 大文字に変換
df['upper'] = df['name'].str.upper()
# 小文字に変換
df['lower'] = df['name'].str.lower()
# 先頭だけ大文字
df['title'] = df['name'].str.title()
よく使うメソッド
文字列操作でよく使うメソッドを紹介します。
| メソッド | 説明 |
|---|---|
| str.upper() | 大文字に変換 |
| str.lower() | 小文字に変換 |
| str.strip() | 前後の空白を削除 |
| str.replace() | 文字列を置換 |
| str.split() | 分割してリストに |
| str.len() | 文字数を取得 |
| str.contains() | パターンを含むか |
| str.startswith() | 指定文字で始まるか |
| str.endswith() | 指定文字で終わるか |
文字列の置換
str.replace で文字列を置換できます。
df = pd.DataFrame({
'text': ['hello-world', 'foo-bar', 'test-data']
})
# ハイフンをアンダースコアに
df['text'] = df['text'].str.replace('-', '_')
# 正規表現で置換
df['text'] = df['text'].str.replace(r'\d+', '', regex=True)
文字列の分割
str.split で文字列を分割し、特定の部分を取り出せます。
df = pd.DataFrame({
'email': ['alice@example.com', 'bob@test.org']
})
# @ で分割してユーザー名を取得
df['user'] = df['email'].str.split('@').str[0]
# ドメインを取得
df['domain'] = df['email'].str.split('@').str[1]
expand=True を指定すると、分割結果を複数列に展開できます。
df[['user', 'domain']] = df['email'].str.split('@', expand=True)
部分文字列の抽出
str.extract で正規表現を使ってパターンを抽出できます。
df = pd.DataFrame({
'text': ['Price: $100', 'Cost: $250', 'Fee: $50']
})
# 数字を抽出
df['price'] = df['text'].str.extract(r'(\d+)')
グループを複数使うと、複数列を一度に抽出できます。
df = pd.DataFrame({
'info': ['Alice:25', 'Bob:30', 'Charlie:35']
})
df[['name', 'age']] = df['info'].str.extract(r'(\w+):(\d+)')
条件フィルタリング
str.contains でパターンマッチングによるフィルタリングができます。
df = pd.DataFrame({
'product': ['Apple iPhone', 'Samsung Galaxy', 'Apple iPad', 'Google Pixel']
})
# Apple を含む行だけ抽出
apple_products = df[df['product'].str.contains('Apple')]
# 正規表現で検索
phones = df[df['product'].str.contains(r'Phone|Galaxy|Pixel', regex=True)]
str.startswith や str.endswith も便利です。
# .com で終わるメールアドレス
df[df['email'].str.endswith('.com')]
# http で始まる URL
df[df['url'].str.startswith('http')]
NaN の扱い
str アクセサは NaN を自動的にスキップします。結果も NaN になります。
df = pd.DataFrame({
'name': ['Alice', None, 'Charlie']
})
df['upper'] = df['name'].str.upper()
# None の行は NaN になる
na パラメータでデフォルト値を指定できるメソッドもあります。
# NaN は False として扱う
df[df['name'].str.contains('li', na=False)]
str アクセサを使いこなすと、文字列データの前処理が格段に楽になります。ループで 1 つずつ処理するよりも、コードが読みやすく、実行も高速です。