PandasでSQLのようにデータを結合・集計

プログラミング

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でのデータ操作と分析の効率を大幅に向上させることができます。