Python pandas DataFrameに1行ずつSeriesを追加する。

こんにちは、kisseです。
Pythonのpandasでめっちゃハマった箇所があったので、記事にします。
ベテランの方々からしたら当たり前なのかもしれませんがPython初心者の僕は2時間ハマりました。
きつかったー。

やりたかったこと

空のデータフレームを作成して、1行ずつそれに追加していきます。
データベースからデータを取得して、特定の条件を満たすレコードのみを取り出してデータフレームを生成する処理を行いたかったのです。
SQLで一発で取得することも不可能ではなかったかもしれませんが、普通に処理書いたほうが楽そうな案件だったのでそのようにしました。

書いたコードと問題

このようなコードを書きました。

import pandas as pd

#空のデータフレームを作成
data_frame = pd.DataFrame(index=[], columns=['column1', 'column2'])

#追加する行をSeriesで作成
series = pd.Series(['hoge', 'fuga'], index=data_frame.columns)

#複数回、行を追加する(つもり)
for i in range(5):
    data_frame.append(series, ignore_index = True)
    
data_frame

DataFrameは2次元的なもので、行名列名をそれぞれ指定できます。
しかし、Seriesは1次元的なものであるためindex名しか指定できません。
そのため、index名をDataFrameの列名と指定することにしています。
ループ処理内のappend()メソッドは第一引数に追加するSeries、第2引数にignore_index=Trueを指定することにより追加したSeriesに新たな行番号を与えることができます。
これで、表形式のデータフレームが完成したぜ!、と思ったのですが。。。
結果がこちら

column1	column2

列名しか表示されないという結果に。
え、追加したSeries達どこ行っちゃったの???

正しくは

色々やってみた結果、問題は解決しました。
先ほどのコードのループ処理の内部のappend()を実行した文をdata_frameに再度代入する必要があったのです。

for i in range(5):
#代入しなきゃいけなかった
    data_frame = data_frame.append(series, ignore_index = True)

え、append()って代入しなきゃいけなかったの?
Javaとかだと、append()とかって実行するだけで状態が変更されるの気づけなかったのです。
新しい言語とか使うときはちゃんと仕様確認した方がいいんですね。。。

従って、正しいコードの全文は

import pandas as pd

data_frame = pd.DataFrame(index=[], columns=['column1', 'column2'])
series = pd.Series(['hoge', 'fuga'], index=data_frame.columns)

for i in range(5):
   data_frame = data_frame.append(series, ignore_index = True)
    
data_frame

その実行結果は

column1	column2
0	hoge	fuga
1	hoge	fuga
2	hoge	fuga
3	hoge	fuga
4	hoge	fuga

ちゃんと意図した結果になりました。

最後に

慣れてくると大したことないですけど、最初はびっくりしますね。笑
このようにすることで、DataFrameに1行ずつコードを追加することができますよーって内容でした。
精進します!!!

あわせて読みたい