💭
[Python]Pandasを使ってCSVのデータを結合する
CSV同士で RDBのような結合をしたい
CSVでRDBのテーブル結合のようなことをしたい!ということで今回の記事を書きました。
何か複数のレポートデータを結合したい時とかに便利なのではないでしょうか?
インストール
$ pip install pandas
今回はpandasを使います。そもそもpandasが入ってない方はこちらから
CSVの内容
今回対象にするCSVはこちら。
students.csv
ID,名前,年齢,学校ID
1,山田,15,3
2,佐藤,13,1
3,石田,14,3
4,榊原,14,5
5,五十嵐,12,2
universities.csv
ID,学校名
1,東京大学
2,京都大学
3,名古屋大学
4,神戸大学
内部結合(INNER JOIN)
方法その1
merge.py
import pandas as pd
# まず2つのCSVを読み込む
df = pd.read_csv('./students.csv', encoding='utf-8')
df2 = pd.read_csv('./universities.csv', encoding='utf-8')
# universitiesのIDを学校IDという名前に変更する
df2_ = df2.rename(columns={'ID': '学校ID'})
# 学校IDというキーを元にして2つのCSVを結合する
df_merged = pd.merge(df, df2_, on='学校ID'))
df_merged.to_csv("merged.csv", index=False)
出力結果
ID 名前 年齢 学校ID 学校名
0 1 山田 15 3 名古屋大学
1 3 石田 14 3 名古屋大学
2 2 佐藤 13 1 東京大学
3 5 五十嵐 12 2 京都大学
merged.csv
ID,名前,年齢,学校ID,学校名
1,山田,15,3,名古屋大学
3,石田,14,3,名古屋大学
2,佐藤,13,1,東京大学
5,五十嵐,12,2,京都大学
出力結果を見ればわかりますが、内部結合になっています。
榊原さんに対応する学校がなかったので、その榊原さんの行がなくってしまいましたね。神戸大学もまた然りです。
また、mergeは同じ列名をキーにするようなので、途中でdf2のIDを学校IDに変更して名前を統一しました。
方法その2
merge.py
import pandas as pd
# まず2つのCSVを読み込む
df = pd.read_csv('./students.csv', encoding='utf-8')
df2 = pd.read_csv('./universities.csv', encoding='utf-8')
# dfは学校IDをキーに、df2はIDをキーに内部結合
df_merged = pd.merge(df, df2, left_on='学校ID', right_on='ID')
print(df_merged)
出力結果
ID_x 名前 年齢 学校ID ID_y 学校名
0 1 山田 15 3 3 名古屋大学
1 3 石田 14 3 3 名古屋大学
2 2 佐藤 13 1 1 東京大学
3 5 五十嵐 12 2 2 京都大学
結合するときキーを個別に指定できるのだけど出力結果が気にいらない。一応覚えておこう。
外部結合(OUTER JOIN)
merge.py
import pandas as pd
# まず2つのCSVを読み込む
df = pd.read_csv('./students.csv', encoding='utf-8')
df2 = pd.read_csv('./universities.csv', encoding='utf-8')
# how='outer'を指定
df_merged = pd.merge(df, df2_, on='学校ID', how='outer')
print(df_merged)
df_merged.to_csv("merged.csv", index=False)
出力結果
ID 名前 年齢 学校ID 学校名
0 1.0 山田 15.0 3 名古屋大学
1 3.0 石田 14.0 3 名古屋大学
2 2.0 佐藤 13.0 1 東京大学
3 4.0 榊原 14.0 5 NaN
4 5.0 五十嵐 12.0 2 京都大学
5 NaN NaN NaN 4 神戸大学
merged.csv
ID,名前,年齢,学校ID,学校名
1.0,山田,15.0,3,名古屋大学
3.0,石田,14.0,3,名古屋大学
2.0,佐藤,13.0,1,東京大学
4.0,榊原,14.0,5,
5.0,五十嵐,12.0,2,京都大学
,,,4,神戸大学
なぜかIDが少数になった!原因は不明。
外部結合なので、さっき結合先がいなかった榊原さんと神戸大学が表に現れました。
左外部結合(LEFT OUTER JOIN)
merge.py
import pandas as pd
# まず2つのCSVを読み込む
df = pd.read_csv('./students.csv', encoding='utf-8')
df2 = pd.read_csv('./universities.csv', encoding='utf-8')
# how='left'を指定
df_merged = pd.merge(df, df2_, on='学校ID', how='left')
print(df_merged)
df_merged.to_csv("merged.csv", index=False)
出力結果
ID 名前 年齢 学校ID 学校名
0 1 山田 15 3 名古屋大学
1 2 佐藤 13 1 東京大学
2 3 石田 14 3 名古屋大学
3 4 榊原 14 5 NaN
4 5 五十嵐 12 2 京都大学
merged.csv
ID,名前,年齢,学校ID,学校名
1,山田,15,3,名古屋大学
2,佐藤,13,1,東京大学
3,石田,14,3,名古屋大学
4,榊原,14,5,
5,五十嵐,12,2,京都大学
左外部結合なので榊原さんがの大学がNaNとして表に現れる
右外部結合(RIGHT OUTER JOIN)
merge.py
import pandas as pd
# まず2つのCSVを読み込む
df = pd.read_csv('./students.csv', encoding='utf-8')
df2 = pd.read_csv('./universities.csv', encoding='utf-8')
# how='right'を指定
df_merged = pd.merge(df, df2_, on='学校ID', how='right')
print(df_merged)
df_merged.to_csv("merged.csv", index=False)
出力結果
ID 名前 年齢 学校ID 学校名
0 1.0 山田 15.0 3 名古屋大学
1 3.0 石田 14.0 3 名古屋大学
2 2.0 佐藤 13.0 1 東京大学
3 5.0 五十嵐 12.0 2 京都大学
4 NaN NaN NaN 4 神戸大学
merged.csv
ID,名前,年齢,学校ID,学校名
1.0,山田,15.0,3,名古屋大学
3.0,石田,14.0,3,名古屋大学
2.0,佐藤,13.0,1,東京大学
5.0,五十嵐,12.0,2,京都大学
,,,4,神戸大学
これまたIDが少数になった!原因は不明。(きっと理解不足)
こちらは右外部結合なので、相方が不在の神戸大学に対応する部分はNaNになる。
結論
DataFrameをテーブルのように結合する時は、mergeメソッドにキーワード引数how
に対して、outer
,left
,right
を入れればOK
Discussion
参考になりましたありがとうございます。
この部分ですが、閉じカッコが一つ多いと思います。