pandasで作成したDataFrameに行を追加する方法について。
カラムが同じデータフレームであれば、行を追加するのは簡単だが、カラム名がない場合(DataFrameにSeriesを結合する場合)など、どこまでが許されるのかについて説明する。
結論から言うと、Seriesの結合は上手く動作せず、DataFrame同士の結合にするか、DataFrameを作り直すかが必要になる。
appendとconcat
DataFrameに行を追加する方法として、appendをconcatを使う方法がある。
appendは「将来的に廃止される方向性のためconcatの使用を推奨」とのWarningが表示されるため、今のうちから使用は控えた方が良いと思う。
appendの動作はconcatよりも曖昧でも結合できる場合もあるが、その分、思った通りに結合できているかの確認が必要となるため、個人的には使用しない方が良いと思う。
そのため、本記事ではappendの動作は扱わず、concatを使用して結合する場合について説明する。
DataFrameにDataFrameで行追加する
DataFrameにDataFrameで行追加する場合、お互いの列名が一致している必要がある。
import pandas as pd
data1 = [1, 2, 3]
data2 = [4, 5, 6]
col_names = ["colA", "colB", "colC"]
df1 = pd.DataFrame(data1, columns=col_names)
df2 = pd.DataFrame(data2, columns=col_names)
df_conc = pd.concat([df1, df2], axis=0)
print(df_conc)
>>
colA colB colC
0 1 2 3
0 4 5 6
列名が一致していない場合は、お互いの列を合わせた形になる。
data1 = [[1, 2, 3]]
data2 = [[4, 5, 6]]
col_names = ["colA", "colB", "colC"]
df1 = pd.DataFrame(data1, columns=col_names)
df2 = pd.DataFrame(data2, columns=["colAA", "colB", "colCC"])
df_conc = pd.concat([df1, df2], axis=0)
print(df_conc)
>>
colA colB colC colAA colCC
0 1.0 2 3.0 NaN NaN
0 NaN 5 NaN 4.0 6.0
列名が一致する部分のみ下に結合され、一致しない列名については、値のない部分がNaNになる。
DataFrameにSeriesを行追加する
DataFrameの例で見た通り、DataFrameに行追加する場合、列名が一致している必要がある。
しかし、Seriesには列名がない(インデックスならそれぞれの値に名前を付けられるが)ため、そのままでは上手く結合できない。
そのため、SeriesをDataFrameにしてから結合するか、DataFrameとSeriesをndarrayにして結合してからDataFrameにする必要がある。
SeriesをDataFrameに変換してから結合する
結合先のDataFrameが大きい場合、こちらの方が良いかもしれない。
data1 = [[1, 2, 3]]
data2 = [4, 5, 6]
col_names = ["colA", "colB", "colC"]
df1 = pd.DataFrame(data1, columns=col_names)
sr1 = pd.Series(data2, name="sr1")
df_conc = pd.concat([df1, pd.DataFrame(data=sr1.values.reshape(1, -1), columns=df1.columns)], axis=0)
print(df_conc)
>>
colA colB colC
0 1 2 3
0 4 5 6
Seriesをvaluesでndarrayに変換してreshapeで縦を横向きに変える。
列名には結合先のDataFrameの列名を設定してからconcatで結合する。
DataFrameとSeriesをndarrayに変換して結合する
import numpy as np
import pamdas as pd
data1 = [[1, 2, 3], [4, 5, 6]]
data2 = [7, 8, 9]
col_names = ["colA", "colB", "colC"]
df1 = pd.DataFrame(data1, columns=col_names)
sr1 = pd.Series(data2, name="sr1")
df_conc = pd.DataFrame(np.vstack([df1.values, sr1.values]), columns=df1.columns)
print(df_conc)
>>
colA colB colC
0 1 2 3
1 4 5 6
2 7 8 9
valuesでDataFrameとSeriesをndarrayに変換し、vstackで縦に繋げる。
処理速度やメモリ使用量が問題なければ、こちらの方法でも良いかもしれない。