未経験からデータサイエンティスト

未経験からデータサイエンティストの勉強したことの備忘録とか雑記とか

pythonでpandas.DataFrameを結合する

「毎月記事を書く」宣言してから、1記事も書かないまま2月になっちゃいました。
今月は2記事書かなきゃ。


しばらくは下記書籍の勉強をしていく中で、初めて見たものを備忘録的に書いていきたいと思います。

今回は分析対象のデータ(csv等)が複数のデータに散らばっている場合に、それをpythonのpandasに入れてから結合する関数、メソッドについてを書いていきます。 


「concat」でのcolumns方向に結合

下記のdf1, df2をpandas.concat()で以下のように結合することができます。

import pandas as pd

df1 = pd.DataFrame({"a": ["a1", "a2", "a3"],
                    "b": ["b1", "b2", "b3"],
                    "c": ["c1", "c2", "c3"],
                    "d": ["d1", "d2", "d3"]},
                    index=[0, 1, 2])

df2 = pd.DataFrame({"a": ["a4", "a5", "a6", "a7"],
                    "b": ["b4", "b5", "b6", "b7"],
                    "c": ["c4", "c5", "c6", "c7"],
                    "d": ["d4", "d5", "d6", "d7"]},
                    index=[3, 4, 5, 6])

df_result1 = pd.concat([df1, df2])

f:id:sue124:20200213061551p:plain

引数のリストの中身を増やせば、3つ以上DataFrameを結合することもできます。

df3 = pd.DataFrame({"a": ["a7", "a8"],
                    "b": ["b7", "b8"],
                    "c": ["c7", "c8"],
                    "d": ["d7", "d8"]},
                   index=[7, 8])

df_result2 = pd.concat([df1, df2, df3])
df_result2

f:id:sue124:20200219060823p:plain

columnが異なるDataframで実施すると以下のようになります。
元のDataFrameではデータが存在しなかった部分には"NaN" (Not a Number) が入ります。

df4 = pd.DataFrame({"a": ["a2", "a5", "a8"],
                    "b": ["b2", "b5", "b8"],
                    "z": ["z2", "z5", "z8"],},
                   index=[2, 5, 8])
df4

df_result3 = pd.concat([df1, df4])

f:id:sue124:20200219061617p:plain

上記では元のDataFrameのindexがそのまま使われていますが、 ignore_index=True を指定するとindexをゼロから連番で振り直すことができます。

df_result4 = pd.concat([df1, df4], ignore_index=True)

f:id:sue124:20200220062810p:plain

「concat」でのindex方向に結合
index方向に連結したい場合は、axis=1 を指定します。
なお上記でこれまで紹介したcolumn方向への結合を明示的に実施するには axis=0 (デフォルト) を指定します。

df_result5 = pd.concat([df1, df4], axis=1)

f:id:sue124:20200220062841p:plain

これまでは元のDataFrameの全てのデータが残っていましたが join="inner" を指定すると共通のラベルのみを残して連結することになります。
なお全てのデータを残して結合するのを明示的するには、join="outer" (デフォルト) を指定します。

df_result6 = pd.concat([df1, df4], axis=1, join="inner")

f:id:sue124:20200220062914p:plain

特定のラベルのみを指定する場合は、join_axes で指定します。

df_result7 = pd.concat([df1, df4], axis=1, join_axes=[df1.index])

f:id:sue124:20200220063017p:plain


index方向への結合時、indexが重複して見づらい場合がある。
このような時は keysで指定したラベルを追加することができる。

df_result8 = pd.concat([df1, df4], axis=1, keys=["X", "Y"])

f:id:sue124:20200220063357p:plain



「append」での結合

concatで大抵の結合はできるのですが、 DataFrame.append でよりシンプルに書けるようです。

df1.append(df2)

f:id:sue124:20200221232221p:plain

2つ以上のDataFrameをappendする場合は引数をリストで渡します。

df1.append([df2, df4])

f:id:sue124:20200221232323p:plain

1行だけを追加する場合はpandas.Seriesを引数に設定します。
nameをして指定ない場合は、ignore_index=True を指定するとエラーにならず、append元のindexの続きの番号が振られるようです。

s1 = pd.Series(["x0", "x1", "x2", "x3"],
               index=["a", "b", "c", "d"], name=10)
df1.append(s1)

f:id:sue124:20200222231411p:plain


まとめ
pandas.concat でcolumn方向、index方向にDataFrameを結合できる
DataFrame.append でも可(よりシンプルに書ける)