PandasによるSQLライクなデータ操作
Pandasは、Pythonでデータ分析を行うための強力なライブラリです。特に、SQLの操作に慣れているユーザーにとって、Pandasは非常に直感的で使いやすいツールとなります。SQLのJOINやGROUP BYといった基本的な操作を、PandasのDataFrameオブジェクトを用いてPythonコードで実現できます。ここでは、PandasでSQLライクなデータ結合、集計、および関連する操作について、詳しく解説します。
データ結合 (JOIN)
SQLにおけるJOIN操作は、複数のテーブル(PandasではDataFrame)を、共通のキー(列)を元に結合する機能です。Pandasでは、merge関数がこの役割を担います。
内部結合 (INNER JOIN)
SQLのINNER JOINは、両方のテーブルに共通するキーを持つ行のみを結合します。Pandasのmerge関数でhow=’inner’を指定することで実現できます。
import pandas as pd
# サンプルDataFrameの作成
df1 = pd.DataFrame({‘key’: [‘A’, ‘B’, ‘C’, ‘D’],
‘value1’: [1, 2, 3, 4]})
df2 = pd.DataFrame({‘key’: [‘B’, ‘D’, ‘E’, ‘F’],
‘value2′: [5, 6, 7, 8]})
# 内部結合
inner_join_df = pd.merge(df1, df2, on=’key’, how=’inner’)
print(“— Inner Join —“)
print(inner_join_df)
この例では、`key`列が’B’と’D’の行が結合されます。
左外部結合 (LEFT OUTER JOIN)
SQLのLEFT OUTER JOINは、左側のテーブルの全ての行を含み、右側のテーブルには一致する行があれば結合し、なければ欠損値(NaN)で埋めます。Pandasではhow=’left’を指定します。
# 左外部結合
left_join_df = pd.merge(df1, df2, on=’key’, how=’left’)
print(“n— Left Outer Join —“)
print(left_join_df)
`df1`の全ての行が表示され、`df2`に`key`が一致しない行(’A’, ‘C’)では`value2`がNaNとなります。
右外部結合 (RIGHT OUTER JOIN)
SQLのRIGHT OUTER JOINは、右側のテーブルの全ての行を含み、左側のテーブルには一致する行があれば結合し、なければ欠損値(NaN)で埋めます。Pandasではhow=’right’を指定します。
# 右外部結合
right_join_df = pd.merge(df1, df2, on=’key’, how=’right’)
print(“n— Right Outer Join —“)
print(right_join_df)
`df2`の全ての行が表示され、`df1`に`key`が一致しない行(’E’, ‘F’)では`value1`がNaNとなります。
完全外部結合 (FULL OUTER JOIN)
SQLのFULL OUTER JOINは、左右両方のテーブルの全ての行を含み、一致しない場合は欠損値(NaN)で埋めます。Pandasではhow=’outer’を指定します。
# 完全外部結合
outer_join_df = pd.merge(df1, df2, on=’key’, how=’outer’)
print(“n— Full Outer Join —“)
print(outer_join_df)
`df1`と`df2`の全ての`key`が含まれ、対応する値がない場合はNaNが挿入されます。
結合キーの指定
結合するキーが左右のDataFrameで異なる名前の場合、left_onとright_on引数を使用します。
df3 = pd.DataFrame({‘id’: [‘A’, ‘B’, ‘C’, ‘D’],
‘value3’: [10, 11, 12, 13]})
df4 = pd.DataFrame({‘user_id’: [‘B’, ‘D’, ‘E’, ‘F’],
‘value4′: [14, 15, 16, 17]})
merged_diff_keys = pd.merge(df3, df4, left_on=’id’, right_on=’user_id’, how=’inner’)
print(“n— Merge with Different Keys —“)
print(merged_diff_keys)
この場合、両方のキー列(`id`と`user_id`)が結果に含まれます。
複数キーによる結合
複数の列をキーとして結合することも可能です。on引数に列名のリストを渡します。
df5 = pd.DataFrame({‘key1’: [‘A’, ‘A’, ‘B’, ‘B’],
‘key2’: [‘X’, ‘Y’, ‘X’, ‘Y’],
‘value5’: [1, 2, 3, 4]})
df6 = pd.DataFrame({‘key1’: [‘A’, ‘B’, ‘B’, ‘C’],
‘key2’: [‘X’, ‘X’, ‘Y’, ‘Z’],
‘value6’: [5, 6, 7, 8]})
multi_key_merge = pd.merge(df5, df6, on=[‘key1’, ‘key2′], how=’inner’)
print(“n— Merge with Multiple Keys —“)
print(multi_key_merge)
append/concat
SQLには直接対応する概念ではありませんが、DataFrameを縦に結合するconcat関数(以前はappend)も、データ操作において重要です。これは、基本的に同一構造のテーブルを積み重ねるイメージです。
df7 = pd.DataFrame({‘col1’: [1, 2], ‘col2’: [3, 4]})
df8 = pd.DataFrame({‘col1’: [5, 6], ‘col2’: [7, 8]})
concatenated_df = pd.concat([df7, df8], ignore_index=True) # ignore_index=Trueでインデックスを振り直す
print(“n— Concatenation —“)
print(concatenated_df)
### データ集計 (GROUP BY)
SQLのGROUP BY句は、特定の列の値に基づいてデータをグループ化し、各グループに対して集計関数(SUM, AVG, COUNTなど)を適用します。Pandasでは、groupby()メソッドがこの機能を提供します。
基本的なグループ化と集計
data = {‘category’: [‘A’, ‘B’, ‘A’, ‘B’, ‘A’, ‘C’],
‘value’: [10, 15, 12, 18, 11, 20],
‘count’: [1, 2, 1, 3, 2, 1]}
df_group = pd.DataFrame(data)
# categoryでグループ化し、valueの合計を計算
grouped_sum = df_group.groupby(‘category’)[‘value’].sum()
print(“n— Group By Sum —“)
print(grouped_sum)
# categoryでグループ化し、valueの平均を計算
grouped_mean = df_group.groupby(‘category’)[‘value’].mean()
print(“n— Group By Mean —“)
print(grouped_mean)
# categoryでグループ化し、countの合計を計算
grouped_count_sum = df_group.groupby(‘category’)[‘count’].sum()
print(“n— Group By Count Sum —“)
print(grouped_count_sum)
複数の集計
agg()メソッドを使用すると、一つのグループ化操作で複数の集計関数を適用できます。
# categoryでグループ化し、valueの合計と平均、countの合計を計算
multi_agg = df_group.groupby(‘category’).agg(
value_sum=(‘value’, ‘sum’),
value_mean=(‘value’, ‘mean’),
count_sum=(‘count’, ‘sum’)
)
print(“n— Group By Multiple Aggregations —“)
print(multi_agg)
複数列でのグループ化
複数の列をキーとしてグループ化することも可能です。
data_multi_key = {‘key1’: [‘A’, ‘A’, ‘B’, ‘B’, ‘A’, ‘B’],
‘key2’: [‘X’, ‘Y’, ‘X’, ‘Y’, ‘X’, ‘X’],
‘value’: [10, 15, 12, 18, 11, 20]}
df_multi_key_group = pd.DataFrame(data_multi_key)
# key1とkey2でグループ化し、valueの合計を計算
multi_key_grouped = df_multi_key_group.groupby([‘key1’, ‘key2’])[‘value’].sum()
print(“n— Group By Multiple Keys —“)
print(multi_key_grouped)
集計結果のリセット
groupby()の結果はSeriesまたはDataFrameになりますが、グループ化キーを通常の列に戻したい場合はreset_index()を使用します。
reset_index_sum = grouped_sum.reset_index()
print(“n— Group By Sum with Reset Index —“)
print(reset_index_sum)
その他のSQLライクな操作
データの選択とフィルタリング
SQLのWHERE句に相当するのが、PandasのBoolean indexingです。
# valueが15より大きい行を選択
filtered_df = df_group[df_group[‘value’] > 15]
print(“n— Filtering (WHERE clause) —“)
print(filtered_df)
# categoryが’A’または’B’の行を選択
filtered_or_df = df_group[df_group[‘category’].isin([‘A’, ‘B’])]
print(“n— Filtering (OR condition) —“)
print(filtered_or_df)
データの並べ替え (ORDER BY)
SQLのORDER BY句は、Pandasのsort_values()メソッドで実現できます。
# value列で昇順に並べ替え
sorted_df = df_group.sort_values(by=’value’, ascending=True)
print(“n— Sorting (ORDER BY) —“)
print(sorted_df)
# 複数の列で並べ替え(categoryで昇順、valueで降順)
sorted_multi_df = df_group.sort_values(by=[‘category’, ‘value’], ascending=[True, False])
print(“n— Sorting by Multiple Columns —“)
print(sorted_multi_df)
データの選択 (SELECT)
SQLのSELECT句は、DataFrameの列を選択することで実現します。
# categoryとvalue列のみを選択
selected_columns = df_group[[‘category’, ‘value’]]
print(“n— Column Selection (SELECT clause) —“)
print(selected_columns)
DISTINCT (UNIQUE)
SQLのDISTINCTは、Pandasではunique()やdrop_duplicates()で実現できます。
# category列のユニークな値を取得
unique_categories = df_group[‘category’].unique()
print(“n— Unique Values (DISTINCT) —“)
print(unique_categories)
# 重複行を削除
df_deduplicated = df_group.drop_duplicates(subset=[‘category’])
print(“n— Dropping Duplicates —“)
print(df_deduplicated)
LIMIT / HEAD
SQLのLIMIT句は、Pandasのhead()メソッドで実現できます。
# 最初の3行を表示
print(“n— First 3 Rows (LIMIT 3) —“)
print(df_group.head(3))
OFFSET / SKIP
PandasでOFFSETを模倣するには、スライシングとtail()を組み合わせるか、ilocを使用します。
# 3行目から5行目まで(OFFSET 2, LIMIT 3相当)
print(“n— Rows from 3rd to 5th (OFFSET 2, LIMIT 3) —“)
print(df_group.iloc[2:5])
まとめ
Pandasは、その柔軟性と豊富な機能により、SQLの操作をPython環境で効果的に模倣することを可能にします。merge関数による多様な結合方法、groupby()とagg()による強力な集計機能、そしてBoolean indexingやsort_values()といった操作は、データ分析におけるSQLライクなワークフローをスムーズに実行するために不可欠です。これらの機能を理解し使いこなすことで、Pythonでのデータ操作と分析の効率を大幅に向上させることができます。
