最終更新日:2021/8/26
dfどうしの結合、連結の方法を説明します。ここでは、特に縦方向(行方向)への結合、連結を扱います。
このページでは、「結合」と「連結」はほぼ同じ意味で用いています。
幾つか方法がありますが、ここでは、目的への一番の近道と思われる方法だけを扱います。
【説明すること】
- 1. はじめに
- 2. df+dfの結合 :
pd.concat([df1, df2], axis=0, ignore_index=True)
- 3. df+seの結合 :
df.append(se, ignore_index=True)
- 参考HP
1. はじめに
縦方向(行方向)への結合・連結は、欠損値が生じないようにする為には、基本的には元のdfと、追加するdfで、同じカラム名(列名)を持っていなければなりません。
例えば、Excelのように1-5行目と6-10行目で違うカラム名のものを結合する、というのは簡単にはできません。
また、indexとカラム名(列名)を常に意識することが重要です。
カラム名、indexを意識する、ということはlistでは結合ができず、基本的にはDataFrame(df)かSeries(se)を結合・連結の対象に扱うことになります。
なぜならば、listにはそれらの考え方が無いからです。
尚、縦への結合は1行を追加する、という操作にも応用できます。
2. df+dfの結合 : pd.concat()
dfにdfを結合する場合、
pd.concat([df1, df2], axis=0, ignore_index=True)
を使います。
axis=0
は方向を指定するオプションで、縦方向(行方向)という意味で、よく使います。
他にaxis=1
があり、これは横方向(列方向)という意味です。
また、ignore_index=True
は、結合したdfのindexを振り直します。振り直す必要がない場合は、省略できます。または、ignore_index=False
を指定します。
・カラム名(列名)が一致しない場合
結合の対象とするdf1とdf2のカラム名が一致しない場合、結合したdfに、不一致なカラムが追加されます。
以下のcsvファイルを読み込んで例を挙げます。
a004_010a_a.csv, a004_010a_b.csv, a004_010a_c.csv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import pandas as pd
f1a = r'C:\Users\shilabo\Documents\SHiLABO_python\a004_010a_a.csv'
f1b = r'C:\Users\shilabo\Documents\SHiLABO_python\a004_010a_b.csv'
f1c = r'C:\Users\shilabo\Documents\SHiLABO_python\a004_010a_c.csv'
df1a = pd.read_csv(f1a)
df1b = pd.read_csv(f1b)
df1c = pd.read_csv(f1c)
print(df1a)
# clm0 clm1
#0 A0 B0
#1 A1 B1
print(df1b)
# clm0 clm1
#0 a0 b0
#1 a1 b1
print(df1c)
# clm0 clm1 clm90
#0 a0 b0 x0
#1 a1 b1 x1
#1. .concat[df, df]
df2ab = pd.concat([df1a, df1b], axis=0)
print(df2ab)
# clm0 clm1
#0 A0 B0
#1 A1 B1
#0 a0 b0
#1 a1 b1
# ignore_index = True
df2abT = pd.concat([df1a, df1b], axis=0, ignore_index=True)
print(df2abT)
# clm0 clm1
#0 A0 B0
#1 A1 B1
#2 a0 b0
#3 a1 b1
df2ac = pd.concat([df1a, df1c], axis=0) #カラム名が一致しない場合。
print(df2ac)
# clm0 clm1 clm90
#0 A0 B0 NaN
#1 A1 B1 NaN
#0 a0 b0 x0
#1 a1 b1 x1
3. df+seの結合 : df.append(se)
dfとseを結合する場合は、
df.append(se, ignore_index=True)
と書きます。ignore_index=True
は、上記2.と同じで、結合したdfのindexを振り直します。振り直す必要がない場合は、省略できます。
結合するseのindex(seにカラム名は無い)が、対象のdfのカラム名と一致するか、で分けておきます。理屈は同じですが、違いをはっきりさせる為です。
3.1. seのindexがdfのカラム名と一致する場合3.2. seのindexがdfのカラム名と一致しない場合
他にも、pd.concat([df, se])
を使う方法などがありますが、多くの場合、必要とする結果はdf.append()
だと思います。
これ以外は、複雑なので、ここでは省略します。
尚、seはdfの1列を抜き出したものでもあるので、dfに1行を追加する場合も、この操作で実現します。
コードを書く際は、indexとカラム名を意識してください。
3.1. seのindexがdfのカラム名と一致する場合
df.append(se, ignore_index=True)
と書きます。ignore_index=True
は、前出の通りです。
この場合、dfの一番下にseが追加されます。seが横向きで下に追加されるイメージで、行の追加という感じです。そして、結合後のdfのindex名がseのnameになります。
これが、多くのケースで必要とされる結果だと思います。
繰り返しになりますが、indexとカラム名、そしてseのnameを意識する事がとても重要です。
・結合後のdfのindex名(縦方向のラベル) = seのname
・結合後のdfのカラム名(横方向のラベル) = seのindex名 = もとのdfのカラム名
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#(1)seのindexが一致する場合
#df1cからseriesにして、カラム名を同じにする
se3a = df1c['clm90'].copy()
se3a.index = ['clm0', 'clm1']
print(se3a)
#clm0 x0
#clm1 x1
#Name: clm90, dtype: object
df3a = df1a.append(se3a)
print(df3a)
# clm0 clm1
#0 A0 B0
#1 A1 B1
#clm90 x0 x1 #<=横向きで最終行へ
他のdfから1行をコピーして張り付ける場合は、以下のようになります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#例: 他の1行をコピーして下に貼付け
se3c = df1b.iloc[0,:] #<=0行目だけ。これはSeries。
print(se3c)
#clm0 a0
#clm1 b0
#Name: 0, dtype: object
df3c = df1a.append(se3c)
print(df3c)
# clm0 clm1
#0 A0 B0
#1 A1 B1
#0 a0 b0
3.2. seのindexがdfのカラム名と一致しない場合
同じく、
df.append(se, ignore_index=True)
と書きます。ignore_index=True
は、前出の通りです。
この場合、カラムが追加され、そのカラム名がseのindex名となります。seが横向きで右にとって付けるイメージです。結合した結果のdfのindex名がseのnameになります。
結合後のdfのindex名(縦方向のラベル) = seのname
結合後のdfのカラム名(横方向のラベル) = もとのdfのカラム名 + 不一致なseのindex名
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#(2)seのindexが一致しない場合
#df1cからseriesにして、カラム名を異なるものにする。
se3b = df1c['clm90'].copy()
se3b.index = [10, 11]
#これは、以下と同じこと。
#se3b = pd.Series(['x0', 'x1'], index=[10, 11], name='clm90')
print(se3b)
#10 x0
#11 x1
#Name: clm90, dtype: object #<= 「name='clm90'」に注目
df3a = df1a.append(se3b)
print(df3a)
# clm0 clm1 10 11
#0 A0 B0 NaN NaN
#1 A1 B1 NaN NaN
#clm90 NaN NaN x0 x1 #<=これがse3b
参考HP
以下のHPがとても詳しいので、参考にしてください。図があって、とても分かりやすいです。
https://sinhrks.hatenablog.com/entry/2015/01/28/073327