web-dev-qa-db-ja.com

PandasでDataFrameの行を反復する方法

私はパンダからDataFrameを持っています:

import pandas as pd
inp = [{'c1':10, 'c2':100}, {'c1':11,'c2':110}, {'c1':12,'c2':120}]
df = pd.DataFrame(inp)
print df

出力:

   c1   c2
0  10  100
1  11  110
2  12  120

今度はこのフレームの行を反復したいと思います。すべての行について、列の名前でその要素(セル内の値)にアクセスできるようにしたいです。例えば:

for row in df.rows:
   print row['c1'], row['c2']

パンダでそれをすることは可能ですか?

私はこれを見つけました 同じような質問 しかし、それは私が必要とする答えを私に与えません。例えば、それを使用することがそこで提案されています:

for date, row in df.T.iteritems():

または

for row in df.iterrows():

しかし、私はrowオブジェクトが何であるか、そしてそれをどのように扱うことができるかを理解していません。

1195
Roman

DataFrame.iterrows はインデックスと行の両方を生成するジェネレータです。

for index, row in df.iterrows():
    print(row['c1'], row['c2'])

Output: 
   10 100
   11 110
   12 120
1713
waitingkuo

パンダでDataFrameの行を反復処理するには、次のようにします。

itertuples()iterrows()より速いとされています

しかし、注意してください、ドキュメントによると(現時点でパンダ0.21.1):

  • iterrows:dtypeは行ごとに一致しない可能性があります

    Iterrowsは各行に対してSeriesを返すので、 は行全体で dtypesを保持しません(dtypesはDataFrameの列全体で保持されます)。

  • iterrows:行を変更しません

    絶対に 変更しないでください。これがすべての場合に機能することが保証されているわけではありません。データ型によっては、イテレータはビューではなくコピーを返すので、それに書き込んでも効果はありません。

    代わりに DataFrame.apply() を使用してください。

    new_df = df.apply(lambda x: x * 2)
    
  • itertuples:

    列名が無効なPython識別子である場合、列名が定位置名に変更されるか、繰り返されるか、またはアンダースコアで始まります。列数が多い(> 255)場合、通常のタプルが返されます。

258
viddik13

df.iterrows() を使うべきです。ただし、Seriesオブジェクトを作成する必要があるため、行ごとの繰り返しは特に効率的ではありません。

183
Wes McKinney

iterrows()は良い選択肢ですが、itertuples()のほうがずっと速いことがあります。

df = pd.DataFrame({'a': randn(1000), 'b': randn(1000),'N': randint(100, 1000, (1000)), 'x': 'x'})

%timeit [row.a * 2 for idx, row in df.iterrows()]
# => 10 loops, best of 3: 50.3 ms per loop

%timeit [row[1] * 2 for row in df.itertuples()]
# => 1000 loops, best of 3: 541 µs per loop
140
e9t

df.apply()を使用して行を反復処理し、関数の複数の列にアクセスすることもできます。

docs:DataFrame.apply()

def valuation_formula(x, y):
    return x * y * 0.5

df['price'] = df.apply(lambda row: valuation_formula(row['x'], row['y']), axis=1)
75
cheekybastard

次のようにdf.iloc関数を使うことができます。

for i in range(0, len(df)):
    print df.iloc[i]['c1'], df.iloc[i]['c2']
67
PJay

私は探していました どのように行と列を反復処理してここで終了しました:

for i, row in df.iterrows():
    for j, column in row.iteritems():
        print(column)
27
Lucas B

Q:PandasでDataFrameの行を反復する方法は?

しないでください。

パンダでの繰り返しは反パターンであり、あなたが可能な限り他のすべての選択肢を使い果たしたときにあなたがしたいと思う何かです。あなたは、数千行を超えるものに対して、名前に "iter"を持つ関数を使うことを考えてはいけません。そうしないと、 lot に慣れる必要があります。

データフレームを印刷しますか。 DataFrame.to_string() を使用してください。

何か計算したいですか?その場合は、次の順序でメソッドを検索してください( here から変更されたリスト)。

  1. ベクトル化
  2. Cythonのルーチン
  3. 内包表記の一覧表示(forループ)
  4. DataFrame.apply()
    私。 cythonで実行できる削減
    ii。 Python空間での繰り返し
  5. DataFrame.itertuples() および iteritems()
  6. DataFrame.iterrows()

iterrowsitertuples(どちらもこの質問に対する回答で多数の投票を受けています)は、逐次処理のために行オブジェクト/名前組を生成するなど、非常にまれな状況で使用するべきです。

当局に訴える
ドキュメントページ 繰り返しの際に、次のような大きな赤い警告ボックスが表示されます。

パンダオブジェクトを繰り返し処理するのは一般に遅いです。多くの場合、行を手動で繰り返す必要はありません[...]。


ループよりも速い: ベクトル化Cython

基本的な操作や計算のかなりの数がパンダによって(ベクトル化されて)(NumPyを通して、あるいはCython化された関数を通して)行われます。これには、算術演算、比較、(ほとんどの)縮小、(ピボットなどの)再整形、結合、およびグループ化操作が含まれます。あなたの問題に適したベクトル化された方法を見つけるために Essential Basic Functionality のドキュメントを見てください。

何も存在しない場合は、カスタムの cython拡張機能 を使用して自由に自分のものを書いてください。


次の最善のこと: リストの内包表記

利用可能なベクトル化された解決策がなく、パフォーマンスが重要である(しかしコードをcythonizingする煩わしさを経験するのに十分重要ではない)ために反復している場合は、次の最善/最も単純なオプションとしてリスト内包表記を使用します。

単一の列を使用して行を反復するには、次のようにします。

result = [f(x) for x in df['col']]

複数の列を使用して行を反復するには、次のようにします。

# two column format
result = [f(x, y) for x, y in Zip(df['col1'], df['col2'])]

# many column format
result = [f(row[0], ..., row[n]) for row in df[['col1', ...,'coln']].values]

繰り返し処理中に整数の行インデックスが必要な場合は、 enumerate を使用します。

result = [f(...) for i, row in enumerate(df[...].values)]

df.index[i]はインデックスラベルを取得します)

もしそれを関数に変えることができれば、リスト内包表記を使うことができます。生のpythonの単純さとスピードによって、あなたは任意に複雑なものをうまく動作させることができます。

23
cs95

namedtupleを実装する独自のイテレータを書くことができます

from collections import namedtuple

def myiter(d, cols=None):
    if cols is None:
        v = d.values.tolist()
        cols = d.columns.values.tolist()
    else:
        j = [d.columns.get_loc(c) for c in cols]
        v = d.values[:, j].tolist()

    n = namedtuple('MyTuple', cols)

    for line in iter(v):
        yield n(*line)

これはpd.DataFrame.itertuplesに直接匹敵します。私はより効率的に同じタスクを実行することを目指しています。


私の関数で与えられたデータフレームに対して:

list(myiter(df))

[MyTuple(c1=10, c2=100), MyTuple(c1=11, c2=110), MyTuple(c1=12, c2=120)]

またはpd.DataFrame.itertuplesと一緒に:

list(df.itertuples(index=False))

[Pandas(c1=10, c2=100), Pandas(c1=11, c2=110), Pandas(c1=12, c2=120)]

包括的なテスト
すべての列を使用可能にし、列をサブセット化することをテストします。

def iterfullA(d):
    return list(myiter(d))

def iterfullB(d):
    return list(d.itertuples(index=False))

def itersubA(d):
    return list(myiter(d, ['col3', 'col4', 'col5', 'col6', 'col7']))

def itersubB(d):
    return list(d[['col3', 'col4', 'col5', 'col6', 'col7']].itertuples(index=False))

res = pd.DataFrame(
    index=[10, 30, 100, 300, 1000, 3000, 10000, 30000],
    columns='iterfullA iterfullB itersubA itersubB'.split(),
    dtype=float
)

for i in res.index:
    d = pd.DataFrame(np.random.randint(10, size=(i, 10))).add_prefix('col')
    for j in res.columns:
        stmt = '{}(d)'.format(j)
        setp = 'from __main__ import d, {}'.format(j)
        res.at[i, j] = timeit(stmt, setp, number=100)

res.groupby(res.columns.str[4:-1], axis=1).plot(loglog=True);

enter image description here

enter image description here

15
piRSquared

dataframe内のすべての行をループするためにあなたは使うことができます:

for x in range(len(date_example.index)):
    print date_example['Date'].iloc[x]
13
Pedro Lobito
 for ind in df.index:
     print df['c1'][ind], df['c2'][ind]
12
Grag2015

時には便利なパターンがあります:

# Borrowing @KutalmisB df example
df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]}, index=['a', 'b'])
# The to_dict call results in a list of dicts
# where each row_dict is a dictionary with k:v pairs of columns:value for that row
for row_dict in df.to_dict(orient='records'):
    print(row_dict)

結果は次のとおりです。

{'col1':1.0, 'col2':0.1}
{'col1':2.0, 'col2':0.2}
7
Zach

dataframeおよび各行のの値便利にはを使用)をすべての行でループするには、namedtuplesndarraysに変換できます。次に例を示します。

df = pd.DataFrame({'col1': [1, 2], 'col2': [0.1, 0.2]}, index=['a', 'b'])

行を繰り返します。

for row in df.itertuples(index=False, name='Pandas'):
    print np.asarray(row)

結果は次のとおりです。

[ 1.   0.1]
[ 2.   0.2]

index=TrueインデックスはTupleの最初の要素として追加されます。これはアプリケーションによっては望ましくない場合があります。

6
KutalmisB

値の表示と変更の両方に、iterrows()を使用します。 forループで、タプルのアンパックを使用して(例:i, rowを参照)、値を表示するためだけにrowを使用し、iメソッドでlocメソッドを使用します値を変更したい。前の回答で述べたように、ここでは繰り返し処理しているものを変更しないでください。

for i, row in df.iterrows():
    if row['A'] == 'Old_Value':
        df.loc[i,'A'] = 'New_value'  

ここで、ループ内のrowはその行のコピーであり、ビューではありません。したがって、row['A'] = 'New_Value'のようなものを記述しないでください。DataFrameは変更されません。ただし、iおよびlocを使用して、DataFrameを指定して作業を行うことができます。

2
HKRC

さらにスピードアップするためにnumpyインデックスを作成することもできます。それは実際には反復的ではありませんが、特定のアプリケーションに対する反復よりもはるかにうまく機能します。

subset = row['c1'][0:5]
all = row['c1'][:]

配列にキャストすることもできます。これらのインデックス/選択はすでにNumpy配列のように振る舞うはずですが、私は問題にぶつかり、キャストする必要がありました。

np.asarray(all)
imgs[:] = cv2.resize(imgs[:], (224,224) ) #resize every image in an hdf5 file
1
James L.

なぜ物事を複雑にするのですか?

簡単です。

import pandas as pd
import numpy as np

# Here is an example dataframe
df_existing = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))
for idx,row in df_existing.iterrows():
    print row['A'],row['B'],row['C'],row['D']
1

この例では、ilocを使用してデータフレーム内の各桁を分離しています。

import pandas as pd

 a = [1, 2, 3, 4]
 b = [5, 6, 7, 8]

 mjr = pd.DataFrame({'a':a, 'b':b})

 size = mjr.shape

 for i in range(size[0]):
     for j in range(size[1]):
         print(mjr.iloc[i, j])
1
mjr2000

パンダデータフレームの行を反復処理する方法はたくさんあります。非常に単純で直感的な方法の1つは、次のとおりです。

df=pd.DataFrame({'A':[1,2,3], 'B':[4,5,6],'C':[7,8,9]})
print(df)
for i in range(df.shape[0]):
    # For printing the second column
    print(df.iloc[i,1])
    # For printing more than one columns
    print(df.iloc[i,[0,2]])
1
shubham ranjan