dataframeを結合、連結する方法について
具体例をたくさん紹介しながら解説します
この記事を読むべき方・・・
- Pythonでデータ分析を行うエンジニアやデータサイエンティスト
- pandasを学び始めた初心者
- DataFrame操作の基礎を理解しつつ、次のステップに進みたい中級者
dataframeの欠損値の確認方法を知りたい方
以下の記事で解説していますので参考にしてください
dataframeでのデータ分析について知りたい方
以下の記事で解説していますので参考にしてください
DataFrameの結合とは?
DataFrameの結合は
異なるデータセットを一つに
まとめるための操作です
具体的には、以下のようなものがあります
- 売上データと顧客情報を結合する
- 注文データと商品データを結合して、商品ごとの売上を計算
- 月ごとの売上データを連結して、年間の売上推移を把握
mergeとconcatについて
dataframeを結合する方法には
主にmergeとconcatがあります
それぞれの違いについて簡単に説明しておきます
mergeの使いどころ
concatの使いどころ
merge関数の基本的な使い方
ここでは、以下の内容を解説します
- merge関数の基本的な構文
- on引数とhow引数の使い方
- inner、outer、left、rightの違いと使い分け
mergeの基本的な構文
merge関数の基本構文
pd.merge(left, right, on=None, how='inner', ...)
各引数について
- leftとright:結合する2つのDataFrameを指定
- on:結合のキーとなる列を指定
- how:結合方法を指定(デフォルトはinner)。
merge関数の引数一覧
merge関数にはたくさんの引数があります
各引数を簡単に紹介しておきます
- mergeの引数一覧が知りたい方はこちらをクリック
right
説明: 結合する2つ目のデータフレーム
使用例: df1.merge(df2, on=’key’)
how
説明: 結合方法を指定する
オプション:
inner: 両方のデータフレームに共通するキーのみを保持
outer: 両方のデータフレームにあるすべてのキーを保持
left: 左側のデータフレームのすべてのキーを保持
right: 右側のデータフレームのすべてのキーを保持
使用例: df1.merge(df2, how=’outer’, on=’key’)
on
説明: 結合に使用する列名またはインデックスの名前を指定する
使用例: df1.merge(df2, on=’key’)
left_on
説明: 左側のデータフレームの結合に使用する
列名またはインデックスの名前を指定する
使用例: df1.merge(df2, left_on=’key1′, right_on=’key2′)
right_on
説明: 右側のデータフレームの結合に使用する
列名またはインデックスの名前を指定する
使用例: df1.merge(df2, left_on=’key1′, right_on=’key2′)
left_index
説明: 左側のデータフレームのインデックスを
結合に使用するかどうかを指定する(True または False)
使用例: df1.merge(df2, left_index=True, right_on=’key’)
right_index
説明: 右側のデータフレームのインデックスを
結合に使用するかどうかを指定する(True または False)
使用例: df1.merge(df2, left_on=’key’, right_index=True)
sort
説明: 結合結果をキーでソートするかどうかを指定する(True または False)
使用例: df1.merge(df2, on=’key’, sort=True)
suffixes
説明: 共通の列名に対する接尾辞を指定する(デフォルトは (‘_x’, ‘_y’))
使用例: df1.merge(df2, on=’key’, suffixes=(‘_left’, ‘_right’))
copy
説明: 結合されたデータフレームが
コピーされるかどうかを指定する(True または False)
使用例: df1.merge(df2, on=’key’, copy=False)
indicator
説明: 結合結果にどのデータフレームから行が
来たのかを示す列を追加するかどうかを指定する
True または列名(文字列)を指定すると新しい列が追加される
使用例: df1.merge(df2, on=’key’, indicator=True)
validate
説明: 結合の方法をチェックするためのオプションで
データの一貫性を確認する
one_to_one, one_to_many, many_to_one, many_to_many から選択
使用例: df1.merge(df2, on=’key’, validate=’one_to_many’)
on引数とhow引数の使い方
on 使い方
on引数は、どの列を基に結合するかを指定します
例えば、2つdataframeに“顧客ID”のindexまたはcolumnがあって
それをもとに結合する場合、on=’顧客ID’と指定します
how 使い方
how引数は、結合方法を指定します
指定できるオプションには
inner、outer、left、rightがあります
inner, outer, left, rightの使い分け
merge関数で指定できるhow引数のオプションは
結合するデータの範囲を決定します
Inner Join
両方のDataFrameに共通するキーのデータだけを結合します
Left Join
左側のすべてのデータを保持し
右側に一致するデータがあれば結合します
Right Join
右側のすべてのデータを保持し
左側に一致するデータがあれば結合します
Outer Join
両方のすべてのデータを保持し
欠けている部分はNaNで埋めます。
以下にそれぞれの結合方法の例を示します
import pandas as pd
# サンプルデータ///////////////////////////////////////
# 顧客情報
df1 = pd.DataFrame({
'顧客ID': [1, 2, 3],
'名前': ['山田', '鈴木', '佐藤']
})
print(df1)
顧客ID 名前
0 1 山田
1 2 鈴木
2 3 佐藤
# 注文情報
df2 = pd.DataFrame({
'顧客ID': [1, 2, 4],
'注文金額': [1000, 2000, 3000]
})
print(df2)
顧客ID 注文金額
0 1 1000
1 2 2000
2 4 3000
# Inner Join//////////////////////////////////////////////////
result_inner = pd.merge(df1, df2, on='顧客ID', how='inner')
print(result_inner)
出力結果:
顧客ID 名前 注文金額
0 1 山田 1000
1 2 鈴木 2000
# Left Join///////////////////////////////////////////////////
result_left = pd.merge(df1, df2, on='顧客ID', how='left')
print(result_left)
出力結果:
顧客ID 名前 注文金額
0 1 山田 1000
1 2 鈴木 2000
2 3 佐藤 NaN
# Right Join//////////////////////////////////////////////////
result_right = pd.merge(df1, df2, on='顧客ID', how='right')
print(result_right)
出力結果:
顧客ID 名前 注文金額
0 1 山田 1000
1 2 鈴木 2000
2 4 NaN 3000
# Outer Join//////////////////////////////////////////////////
result_outer = pd.merge(df1, df2, on='顧客ID', how='outer')
print(result_outer)
出力結果:
顧客ID 名前 注文金額
0 1 山田 1000
1 2 鈴木 2000
2 3 佐藤 NaN
3 4 NaN 3000
concat関数の基本的な使い方
ここでは、以下の内容を解説します
- concat関数の基本的な構文
- axis引数を使った縦・横方向の結合方法
concatの基本的な構文
concat関数の基本構文
pd.concat(objs, axis=0, ...)
各引数について
- objs:結合するDataFrameやSeriesのリストを指定
- axis:データをどの方向に結合するかを指定(0:縦(デフォルト),1:横方向)
concatの引数一覧
concat関数にはたくさんの引数があります
今回はそれらを簡単に紹介しておきます
- concatの引数一覧が知りたい方はこちらをクリック
objs
結合するオブジェクト(リストまたは辞書)必須引数
例: pd.concat([df1, df2])
axis
結合する軸を指定
0(デフォルト):行方向に結合(縦方向)
1:列方向に結合(横方向)
例: pd.concat([df1, df2], axis=1)
join
結合方法を指定
‘outer’(デフォルト):すべてのインデックスを保持(外部結合)
‘inner’:共通のインデックスのみ保持(内部結合)
例: pd.concat([df1, df2], join=’inner’)
ignore_index
インデックスを無視してリセットするかどうかを指定
False(デフォルト):元のインデックスを保持
True:新しい連続したインデックスを割り当てる
例: pd.concat([df1, df2], ignore_index=True)
keys
結合された各データフレームやシリーズに
新しいマルチインデックスを割り当てるためのキーを指定
例: pd.concat([df1, df2], keys=[‘A’, ‘B’])
levels
keys を指定した場合に、マルチインデックスのレベルを明示的に指定
例: pd.concat([df1, df2], keys=[‘A’, ‘B’], levels=
- ‘A’, ‘B’, ‘C’]])
names
マルチインデックスの名前を指定
例: pd.concat([df1, df2], keys=[‘A’, ‘B’], names=[‘Group’])
verify_integrity
結合後に重複したインデックスが存在する場合にエラーを発生させるかどうかを指定
False(デフォルト):重複を許可
True:重複があるとエラーを発生させる
例: pd.concat([df1, df2], verify_integrity=True)
sort
結合時に軸をソートするかどうかを指定
False(デフォルト):ソートしない
True:軸をソートする
例: pd.concat([df1, df2], sort=True)
copy
結合する際にデータをコピーするかどうかを指定
True(デフォルト):データをコピー
False:データを直接使用(場合によってはメモリ効率が良くなる)
例: pd.concat([df1, df2], copy=False)
- ‘A’, ‘B’, ‘C’]])
axis引数を使った縦・横方向の結合
axis引数を指定することで
縦方向や横方向にDataFrameを
連結することができます
具体的には、axis=0で縦方向
axis=1で横方向にデータを結合します
import pandas as pd
# サンプルデータ///////////////////////////////////////
# 1月の売上データ
df1 = pd.DataFrame({
'月': ['1月'],
'売上': [3000]
})
prin(df1)
月 売上
0 1月 3000
# 2月の売上データ
df2 = pd.DataFrame({
'月': ['2月'],
'売上': [4000]
})
print(df2)
月 売上
0 2月 4000
# 縦方向に結合(axis=0)/////////////////////////////////////
result_vertical = pd.concat([df1, df2], axis=0)
print(result_vertical)
出力結果:
月 売上
0 1月 3000
0 2月 4000
# 横方向に結合(axis=1)/////////////////////////////////////
result_horizontal = pd.concat([df1, df2], axis=1)
print(result_horizontal)
出力結果:
月 売上 月 売上
0 1月 3000 2月 4000
3つ以上のデータフレームの結合
concat関数は、シンプルなデータの連結に最適です
3つ以上のデータフレームも簡単に連結できます
import pandas as pd
# 各月の売上データ
df1 = pd.DataFrame({'月': ['1月'], '売上': [3000]})
df2 = pd.DataFrame({'月': ['2月'], '売上': [4000]})
df3 = pd.DataFrame({'月': ['3月'], '売上': [5000]})
# 縦方向に連結
result = pd.concat([df1, df2, df3], axis=0, ignore_index=True)
print(result)
出力結果:
月 売上
0 1月 3000
1 2月 4000
2 3月 5000
処理速度upのコツ
大量のデータを操作する際に
処理速度の向上は非常に重要です
以下に処理速度upのコツを紹介しておきます
必要な列だけを選択する
大量のデータを結合する際に
すべての列を使うとメモリ消費が大きくなります
必要な列だけを選択して操作することで
処理速度を向上させることができます
# 必要な列だけを選択して結合
result = pd.merge(df1[['日付', '商品ID']], df2[['商品ID', '売上']], on='商品ID')
メモリ効率を上げるデータ型の変更
データ型を最適化することで
メモリ使用量を削減し、処理速度を向上させることができます
例えば、int64をint32に変更することで
使用メモリを半分に削減できます
# データ型をint64からint32に変更
df1['売上'] = df1['売上'].astype('int32')
print("データ型を最適化したDataFrame:")
print(df1.dtypes)
出力結果:
日付 object
商品ID int64
売上 int32
dtype: object
- int32 と int64 の違いについてはこちらをクリック
int32
- 32ビットの整数型
- 表現できる整数の範囲は、-2,147,483,648 から 2,147,483,647 まで
- 4バイトのメモリを使用
int64
- 64ビットの整数型
- 表現できる整数の範囲は、-9,223,372,036,854,775,808 から 9,223,372,036,854,775,807 まで
- 8バイトのメモリを使用します
よくあるエラーと改善点
最後にデータ結合した際に
よくあるエラーとその改善方法について解説します
データ型の不一致エラー
エラー内容:
異なるデータ型を持つ列でmergeを行うと
以下のようなエラーが発生することがあります
改善点:
結合前に,対象の列のデータ型を統一します
astypeメソッドでデータ型を揃えます
# データ型の統一
df1['商品ID'] = df1['商品ID'].astype(str)
df2['商品ID'] = df2['商品ID'].astype(str)
列名の重複による自動リネーム
エラー内容:
同じ名前の列が両方のDataFrameに存在すると
自動的に_xや_yを付けてリネームされます
改善点:
結合前に、列名が重複しないように
リネームするか、結合後に不要な列を削除し
列名を統一します
# 不要な列の削除と統一
result['売上'] = result['売上_x'].combine_first(result['売上_y'])
result = result.drop(columns=['売上_x', '売上_y'])
インデックスの不一致による意図しない結合
エラー内容:
DataFrameのインデックスが一致していないと
予期しない行が生成されることがあります
改善点:
結合前にインデックスをリセットするか
ignore_index=Trueオプションを
使用して新しいインデックスを作成します
# ignore_index=Trueでインデックスをリセット
result = pd.concat([df1, df2], axis=0, ignore_index=True)
欠損値(NaN)の発生
エラー内容:
片方のDataFrameにしか存在しないデータがあると
欠損値(NaN)が発生します
改善点:
fillnaやcombine_firstを使用して
欠損値を補完することで
データの整合性を保つことができます
result['売上'] = result['売上'].fillna(0) # 欠損値を0で埋める
エラーの多くは
データの前処理不足やデータ型・列名の不一致が原因なので
きちんと確認するようにしていきましょう!