Python3 DataFrameオブジェクトのiterrows()メソッドを使って1行ずつデータを取得する
こんにちは、kisseです。
今日は、Python3で仕事していたときに、ちょこっとハマった箇所について記録を残します。
同様のハマり方してる人にはきっと参考になるよ。
やりたいこと
DataFrameから1行ずつ行を取り出して、データの抽出を行っていました。
その際、DataFrameオブジェクトのiterrows()メソッドの存在を知りましたが、使い方がイマイチわからず困ってました。
iterrows()メソッドを使って処理を簡潔に書きたかったのです。
書いたコード
まず、処理の対象となるDataFrameを用意します。
仕事ではGoogle Big Queryからデータを取得しましたが、この記事では手動でDataFrameを生成します。
import pandas as pd #DataFrameを生成するコード data_frame = pd.DataFrame([['a', 1], ['b', 2], ['c', 3]], columns=['columnA', 'columnB']) data_frame
上記の画像が、今回の記事で対象にするDataFrameです。
では、次に失敗版のコードです。
for value in data_frame.iterrows(): #変数の中にiterrows()で取得したデータを格納 print(value[0]) print(value[1]) # print(value['columnA']) <- エラー発生 #リスト形式になっているようだが、カラム名でデータの取得ができない??
実行結果は、
0 columnA a columnB 1 Name: 0, dtype: object 1 columnA b columnB 2 Name: 1, dtype: object 2 columnA c columnB 3 Name: 2, dtype: object
となります。
for文で指定した変数にはどうやらリスト形式でデータが入ってるようだけど、カラム名ではなぜかエラーがでるし…。
といった状態でした。
しかし、value[1]を表示させたら、どうやらSeriesの形をしていることがわかったのが解決の糸口になりました。
iterrows()メソッドでは、要素が2つのリスト形式で結果が返され、1つ目の要素はインデックス名、2つ目の要素はDataFrameのカラム名がインデックスとなるSeriesオブジェクトの値でした。
修正したコード
先述したように、2つ目の要素にSeriesの形で目的のデータが格納されていることがわかりました。
そこでコードを書き直して,
for i, series in data_frame.iterrows(): #DataFrameオブジェクトのiterrows()メソッドでは、行番号とSeriesがリストとして返ってくる。 #変数を2つ用意すると、それぞれに格納される。 print(i) print(series['columnA'], series['columnB'])
という風に記述を行いました。
変数seriesにSeriesオブジェクト型のデータが格納され、結果カラム名を指定することでデータを参照することができるようになりました。
実行結果はこちら
0 a 1 1 b 2 2 c 3
このように、意図したように1行ごとにデータを参照し、処理を行うことができるようになりました。
また、このコードではfor文に記述した変数は2つでしたが、記述する変数が1つの場合でも少し面倒ですが意図した動作を行うことが可能です。
for value in data_frame.iterrows(): #変数を1つしか用意しないと、リスト番号とカラム名を指定しないと値を得ることができない print(value[0]) print(value[1]['columnA'], value[1]['columnB'])
実行結果は変わりません。
value[1]にSeriesオブジェクトが格納されており、さらにカラム名を指定してあげることにより1行ずつ特定カラムの値を参照することができるようになります。
iterrows()メソッドはリスト形式で、インデックスとSeriesオブジェクトを返すというのがポイントでしたね。
まとめ
DataFrame型のiterrows()メソッドとforループを併用することにより、1行ずつ要素の参照ができるようになる。
その際、for文に記述した変数に格納されるのは、リスト形式でのインデックス名とSeriesオブジェクトの組である。
最後まで読んでいただきありがとうございます!