0Pricing
Pandas & NumPy Academy · レッスン

文字列の分割と置換

.str.split(expand=True)を使って文字列を複数の列に分割し、.str.replace()で部分文字列を置き換えます。

「文字列の分割と置換」はCoddyKit上の無料Pandas & NumPy Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPandas & NumPy Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

文字列をリストに分割する

.str.split(sep)は、Series内の各文字列を区切り文字が現れるたびに分割し、リストのSeriesを返します。expand=Trueを指定しない場合、各要素はPythonのリストになるため、トークン数のカウントや、リスト単位での追加処理に便利です。区切り文字には、リテラル文字列または正規表現パターンを指定できます。

import pandas as pd

df = pd.DataFrame({'tags': ['python,data,pandas', 'ml,ai', 'sql,db,query']})

# Split into a list of strings
df['tag_list'] = df['tags'].str.split(',')
print(df['tag_list'])
# 0    [python, data, pandas]
# 1                  [ml, ai]
# 2         [sql, db, query]

# Count tags per row
df['tag_count'] = df['tag_list'].str.len()
print(df['tag_count'].tolist())  # [3, 2, 3]

expand=Trueで列に分割する

.str.split()にexpand=Trueを渡すと、リストのSeriesではなくDataFrameが返され、分割された各トークンが個別の列(列0、1、2、…)になります。これは区切り文字で分けられた列を横に展開する標準的な方法です。たとえば、'first last'というフルネームを、姓と名の列に分割できます。

import pandas as pd

df = pd.DataFrame({'full_name': ['Alice Smith', 'Bob Jones', 'Carol White']})

# Split into two columns
name_parts = df['full_name'].str.split(' ', expand=True)
name_parts.columns = ['first_name', 'last_name']
df = pd.concat([df, name_parts], axis=1)
print(df)
#     full_name first_name last_name
# 0  Alice Smith      Alice     Smith
# 1    Bob Jones        Bob     Jones
# 2  Carol White      Carol     White

n=で分割数を制限する

nパラメータは、分割の最大回数を制限します。.str.split(sep, n=1)は最大1回だけ分割するため、作成される部分は最大2つです。文字列の最初の要素だけが必要で、残りはまとめておきたい場合に便利です。たとえば、'@'で分割してメールアドレスからドメインを抽出できます。

import pandas as pd

df = pd.DataFrame({'email': ['alice@example.com', 'bob@work.org', 'carol@test.net']})

# Split at '@', keep only the first split
parts = df['email'].str.split('@', n=1, expand=True)
df['username'] = parts[0]
df['domain'] = parts[1]
print(df[['username', 'domain']])
#   username       domain
# 0    alice  example.com
# 1      bob     work.org
# 2    carol     test.net

右側から分割するrsplit()

.str.rsplit(sep, n=1)は文字列の右側から分割します。最後の要素を取得したい場合に便利です。たとえば、パスを最後のドットで分割して、ファイル拡張子を抽出できます。expand=Trueと組み合わせると、最後の区切り文字より前のすべての部分と、後の部分という2つの列が作成されます。

import pandas as pd

df = pd.DataFrame({'filepath': ['data/raw/sales.csv', 'data/clean/orders.xlsx', 'reports/q1.pdf']})

# Split on the last '/' to separate directory from filename
parts = df['filepath'].str.rsplit('/', n=1, expand=True)
df['directory'] = parts[0]
df['filename'] = parts[1]
print(df[['directory', 'filename']])
#     directory    filename
# 0    data/raw   sales.csv
# 1  data/clean  orders.xlsx
# 2     reports       q1.pdf

.str.replace()による部分文字列の置換

.str.replace(pat, repl)は、各文字列内にあるパターンの出現箇所を置換します。デフォルトではpatは正規表現として扱われるため、リテラル文字列を置換する場合はregex=Falseを渡してください。置換には固定文字列または正規表現の後方参照を指定できます。ベクトル化された置換には、Pythonのループではなく、必ずこのメソッドを使用してください。

import pandas as pd

df = pd.DataFrame({'price': ['$1,200.50', '$800.00', '$3,450.75']})

# Remove dollar sign and commas
df['price_clean'] = (
    df['price']
    .str.replace('$', '', regex=False)  # literal $
    .str.replace(',', '', regex=False)  # literal comma
)
df['price_float'] = df['price_clean'].astype(float)
print(df)
#       price price_clean  price_float
# 0  $1,200.50    1200.50       1200.5
# 1    $800.00     800.00        800.0
# 2  $3,450.75    3450.75       3450.75

正規表現パターンで置換する

regex=True(デフォルト)を渡すと、パターンは正規表現として扱われ、置換文字列にはキャプチャしたグループを参照するr'\1'のような後方参照を含められます。これにより、日付の形式変更、電話番号の正規化、自由記述テキストからの構造化データの抽出など、高度なテキスト変換が可能になります。

import pandas as pd

df = pd.DataFrame({'date': ['01-15-2024', '03-20-2024', '07-04-2024']})

# Reformat from MM-DD-YYYY to YYYY-MM-DD using groups
df['date_iso'] = df['date'].str.replace(
    r'(\d{2})-(\d{2})-(\d{4})',
    r'\3-\1-\2',
    regex=True
)
print(df)
#          date   date_iso
# 0  01-15-2024  2024-01-15
# 1  03-20-2024  2024-03-20
# 2  07-04-2024  2024-07-04

置換された件数を数える

置換によって実際に変更された値の数を確認したい場合があります。元のSeriesと置換後のSeriesを比較すると、変更が発生した行の数を数えられます。この検証手順により、置換パターンが想定どおりに一致したことを確認でき、正規表現の誤りも早期に発見できます。

import pandas as pd

df = pd.DataFrame({'text': ['foo bar', 'hello foo', 'world', 'foo foo']})

original = df['text'].copy()
df['text'] = df['text'].str.replace('foo', 'baz', regex=False)

changed = (df['text'] != original).sum()
print(f'{changed} rows were modified')  # 3
print(df['text'].tolist())
# ['baz bar', 'hello baz', 'world', 'baz baz']

ループで複数のパターンを置換する

多数の置換(たとえば、数十種類の略語の標準化)を適用する必要がある場合は、マッピング用の辞書をループ処理し、各置換を順番に適用します。これは、複雑な正規表現のORよりも保守しやすい方法です。業務ルールやルックアップテーブルをもとにマッピングを作成してください。

import pandas as pd

df = pd.DataFrame({'dept': ['Eng', 'Engg', 'HR', 'Human Resources', 'Mktg', 'Marketing']})

# Standardisation map
substitutions = {
    'Engg': 'Engineering',
    'Eng': 'Engineering',
    'Human Resources': 'HR',
    'Mktg': 'Marketing'
}

for old, new in substitutions.items():
    df['dept'] = df['dept'].str.replace(old, new, regex=False)

print(df['dept'].tolist())
# ['Engineering', 'Engineering', 'HR', 'HR', 'Marketing', 'Marketing']

分割した部分を再結合する

分割した後で、各部分を再結合する必要が生じる場合があります。リストのSeriesには.str.join(separator)を使用すると、リスト要素を連結して行ごとに1つの文字列にできます。列をまたいで値を結合する場合は、+と.astype(str)を使った標準的な文字列連結を使用します。

import pandas as pd

df = pd.DataFrame({'parts': [['alpha', 'beta'], ['foo', 'bar', 'baz']]})

# Join list elements with a hyphen
df['joined'] = df['parts'].str.join('-')
print(df['joined'])
# 0     alpha-beta
# 1  foo-bar-baz

空白を正規化する

よくあるテキストクリーニングの作業に、連続する複数の空白を1つの空白にまとめる処理があります。これは、HTMLの空白やコピー&ペーストによって余分な空白が追加された、スクレイピング済みのテキストでよく発生します。正規表現パターンr'\s+'は1つ以上の空白文字に一致し、それらすべてを1つの空白に置換します。その後、.str.strip()で先頭と末尾の空白を削除します。

import pandas as pd

df = pd.DataFrame({'address': ['123  Main   St', '  456 Oak  Ave  ', '789 Pine St']})

df['address_clean'] = (
    df['address']
    .str.replace(r'\s+', ' ', regex=True)
    .str.strip()
)
print(df['address_clean'].tolist())
# ['123 Main St', '456 Oak Ave', '789 Pine St']

実践:構造化された文字列列を解析する

ここでは、1つの列に'Alice:25:Engineer'のような構造化データが含まれている、現実的な例を示します。区切り文字で分割し、生成された列に名前を付け、それぞれを適切な型に変換します。.str.split()とastype()だけを使った、解析から型変換までの完全なパイプラインです。

import pandas as pd

df = pd.DataFrame({'record': ['Alice:25:Engineer', 'Bob:34:Manager', 'Carol:28:Analyst']})

parts = df['record'].str.split(':', expand=True)
parts.columns = ['name', 'age', 'role']
parts['age'] = parts['age'].astype(int)

result = pd.concat([df, parts], axis=1)
print(result)
#              record   name  age      role
# 0  Alice:25:Engineer  Alice   25  Engineer
# 1    Bob:34:Manager    Bob   34   Manager
# 2  Carol:28:Analyst  Carol   28   Analyst

クイックチェック

文字列の分割と置換についての理解度を確認しましょう。

レッスンのまとめ

このレッスンでは、str.split(sep, expand=True)で区切り文字を含む列を複数の列に展開できること、n=で分割数を制限できること、str.rsplit()で右側から分割できること、そしてstr.replace()でパターンを置換できること(正規表現にも対応)を学びました。splitやreplaceの処理をstripやlowerと連結して、完全なテキスト正規化パイプラインを構築できます。次は、正規表現パターンを使って部分文字列を抽出・照合します。

よくある質問

「文字列の分割と置換」レッスンは無料ですか?

はい。「文字列の分割と置換」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Pandas & NumPy Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Pandas & NumPy Academyコースには全4レッスンが含まれています。

「文字列の分割と置換」で何を学びますか?

.str.split(expand=True)を使って文字列を複数の列に分割し、.str.replace()で部分文字列を置き換えます。 ブラウザで直接実行するハンズオンコードでPandas & NumPy Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

Pandas & NumPy Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPandas & NumPy Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「文字列の分割と置換」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPandas & NumPy Academyレッスンでコードを書いて実行できますか?

はい。すべてのPandas & NumPy Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. .strアクセサー
  2. 文字列の分割と置換
  3. 正規表現によるパターンマッチング
  4. テキスト列の結合とクリーニング
← Pandas & NumPy Academyに戻る