2021年2月5日金曜日

結合 - pandas - python

■インポート


import pandas as pd
 以降の呼び出し簡略化のため「pd」と名前を付ける

■テーブル作成


df1 = pd.DataFrame({'列名1':[111,222,333],'列名2':['aaa','bbb','ccc'],'列名3':['a',2,'あ']})
df2 = pd.DataFrame({'列名1':['xxx','yyy','zzz'],'列名2':['aaa','ccc','a'],'列名3':['b','あ',3]})

print(df1)
print(df2)

#出力
#    列名1  列名2 列名3
# 0  111  aaa   a
# 1  222  bbb   2
# 2  333  ccc   あ
#
#    列名1  列名2 列名3
# 0  xxx  aaa   b
# 1  yyy  ccc   あ
# 2  zzz    a   3

■結合


・横に結合

df = pd.merge(df1, df2, on='列名2')
print(df)

#出力
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0    111  aaa     a   xxx     b
# 1    333  ccc     あ   yyy     あ
pd.merge()の第一引数(left)、第二引数(right)にデータフレームを指定
on=で値を比較する列を指定
 デフォルトではinner join(値が等しい行のみ残す)となる
 on=で指定した同名の列はまとめられ
 他の列名が重複していると列名に語尾が追加される

df = pd.merge(df1, df2, left_on='列名3', right_on='列名2')
print(df)

#出力
#    列名1_x 列名2_x 列名3_x 列名1_y 列名2_y 列名3_y
# 0    111   aaa     a   zzz     a     3
 違う列名同士を当てる場合はleft_onright_onでそれぞれ指定

df = pd.merge(df1, df2, on=['列名2','列名3'])
print(df)

#出力
#    列名1_x  列名2 列名3 列名1_y
# 0    333  ccc   あ   yyy
 複数の列を当てる場合はリストで指定

#left join
df = pd.merge(df1, df2, on='列名2', how='left')
print(df)

#right join
df = pd.merge(df1, df2, on='列名2', how='right')
print(df)

#outer join
df = pd.merge(df1, df2, on='列名2', how='outer')
print(df)

#出力
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0    111  aaa     a   xxx     b
# 1    222  bbb     2   NaN   NaN
# 2    333  ccc     あ   yyy     あ
#
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0  111.0  aaa     a   xxx     b
# 1  333.0  ccc     あ   yyy     あ
# 2    NaN    a   NaN   zzz     3
#
#    列名1_x  列名2 列名3_x 列名1_y 列名3_y
# 0  111.0  aaa     a   xxx     b
# 1  222.0  bbb     2   NaN   NaN
# 2  333.0  ccc     あ   yyy     あ
# 3    NaN    a   NaN   zzz     3
how=で結合方法を指定できる
 当たらない行の値はNaNになる

#cross join
df = pd.merge(df1, df2, how='cross')

print(df)

#出力
#    列名1_x 列名2_x 列名3_x 列名1_y 列名2_y 列名3_y
# 0    111   aaa     a   xxx   aaa     b
# 1    111   aaa     a   yyy   ccc     あ
# 2    111   aaa     a   zzz     a     3
# 3    222   bbb     2   xxx   aaa     b
# 4    222   bbb     2   yyy   ccc     あ
# 5    222   bbb     2   zzz     a     3
# 6    333   ccc     あ   xxx   aaa     b
# 7    333   ccc     あ   yyy   ccc     あ
# 8    333   ccc     あ   zzz     a     3
pandas ver1.2.0からcross joinが追加

・縦に結合

#df2に列を追加
df2['列名4'] = 'd'

df = pd.concat( [df1, df2] )
print(df)

#出力
#    列名1  列名2 列名3  列名4
# 0  111  aaa   a  NaN
# 1  222  bbb   2  NaN
# 2  333  ccc   あ  NaN
# 0  xxx  aaa   b    d
# 1  yyy  ccc   あ    d
# 2  zzz    a   3    d
pd.concat()に結合するデータフレームをリストで指定
 同じ列名が結合される
 違う列名がある場合、値がNaNで補完される
 インデックスは元の値を引き継ぐ

#df2に列を追加
df2['列名4'] = 'd'

df = pd.concat( [df1, df2], join='inner', ignore_index=True)
print(df)

#出力
#    列名1  列名2 列名3
# 0  111  aaa   a
# 1  222  bbb   2
# 2  333  ccc   あ
# 3  xxx  aaa   b
# 4  yyy  ccc   あ
# 5  zzz    a   3
join='inner'とすると列名が等しいものだけ残す
ignore_index='True'とするとインデックスがリセットされる

0 件のコメント:

コメントを投稿