note.nkmk.me

pandas.DataFrameのforループ処理(イテレーション)

Date: 2017-12-08 / tags: Python, pandas
このエントリーをはてなブックマークに追加

pandas.DataFrameをfor文でループ処理(イテレーション)する場合、単純にそのままfor文で回すと列名が返ってくるだけなので、繰り返し処理のためのメソッドを使って列ごと・行ごと(一列ずつ・一行ずつ)の値を取得する。

そのままforループにつっこんだ場合は以下のようになる。

import pandas as pd

df = pd.read_csv('data/src/sample_pandas_normal.csv', index_col=0).head(2)
print(df)
#        age state  point
# name                   
# Alice   24    NY     64
# Bob     42    CA     92

for column_name in df:
    print(type(column_name))
    print(column_name)
    print('======\n')
# <class 'str'>
# age
# ======
# <class 'str'>
# state
# ======
# <class 'str'>
# point
# ======

1列ずつ取り出す

DataFrame.iteritems()メソッド

1列ずつ、コラム名(列名)とその列のデータ(pandas.Series型)のペア(column name, Series)を取得できる。

for column_name, item in df.iteritems():
    print(type(column_name))
    print(column_name)
    print(type(item))
    print(item)
    print('------')

    print(item['Alice'])
    print(item[0])
    print(item.Alice)
    print('======\n')
# <class 'str'>
# age
# <class 'pandas.core.series.Series'>
# name
# Alice    24
# Bob      42
# Name: age, dtype: int64
# ------
# 24
# 24
# 24
# ======
# <class 'str'>
# state
# <class 'pandas.core.series.Series'>
# name
# Alice    NY
# Bob      CA
# Name: state, dtype: object
# ------
# NY
# NY
# NY
# ======
# <class 'str'>
# point
# <class 'pandas.core.series.Series'>
# name
# Alice    64
# Bob      92
# Name: point, dtype: int64
# ------
# 64
# 64
# 64
# ======

1行ずつ取り出す

DataFrame.iterrows()メソッド

1行ずつ、インデックス名(行名)とその行のデータ(pandas.Series型)のペア(index, Series)を取得できる。

for index, row in df.iterrows():
    print(type(index))
    print(index)
    print(type(row))
    print(row)
    print('------')

    print(row['point'])
    print(row[2])
    print(row.point)
    print('======\n')
# <class 'str'>
# Alice
# <class 'pandas.core.series.Series'>
# age      24
# state    NY
# point    64
# Name: Alice, dtype: object
# ------
# 64
# 64
# 64
# ======
# <class 'str'>
# Bob
# <class 'pandas.core.series.Series'>
# age      42
# state    CA
# point    92
# Name: Bob, dtype: object
# ------
# 92
# 92
# 92
# ======

DataFrame.itertuples()メソッド

1行ずつ、インデックス名(行名)とその行のデータのタプルを取得できる。タプルの最初の要素がインデックス名となる。

デフォルトではPandasという名前のnamedtupleを返す。namedtupleなので、[]のほか.でも各要素の値にアクセスできる。

for row in df.itertuples():
    print(type(row))
    print(row)
    print('------')

    print(row[3])
    print(row.point)
    print('======\n')
# <class 'pandas.core.frame.Pandas'>
# Pandas(Index='Alice', age=24, state='NY', point=64)
# ------
# 64
# 64
# ======
# <class 'pandas.core.frame.Pandas'>
# Pandas(Index='Bob', age=42, state='CA', point=92)
# ------
# 92
# 92
# ======

引数nameNoneとするとノーマルのタプルを返す。

for row in df.itertuples(name=None):
    print(type(row))
    print(row)
    print('------')

    print(row[3])
    print('======\n')
# <class 'tuple'>
# ('Alice', 24, 'NY', 64)
# ------
# 64
# ======
# <class 'tuple'>
# ('Bob', 42, 'CA', 92)
# ------
# 92
# ======

ループ処理で値を更新する

1行ずつ値を取り出すiterrows()メソッドはビューではなくコピーを返すので、pandas.Seriesを変更しても元データは更新されない。

for index, row in df.iterrows():
    row.point /= 2

print(df)
#        age state  point
# name                   
# Alice   24    NY     64
# Bob     42    CA     92

atで元のDataFrameからデータを選択して処理する必要がある。

for index, row in df.iterrows():
    df.at[index, 'point'] /= 2

print(df)
#        age state  point
# name                   
# Alice   24    NY     32
# Bob     42    CA     46

atについては以下の記事も参照。

なお、上の例のように単純に値を更新するだけであればforループで処理する必要はなく、以下のように書ける。

df['point'] /= 2

print(df)
#        age state  point
# name                   
# Alice   24    NY   16.0
# Bob     42    CA   23.0
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事