私はパンダから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
オブジェクトが何であるか、そしてそれをどのように扱うことができるかを理解していません。
DataFrame.iterrows はインデックスと行の両方を生成するジェネレータです。
for index, row in df.iterrows():
print(row['c1'], row['c2'])
Output:
10 100
11 110
12 120
パンダでDataFrameの行を反復処理するには、次のようにします。
for index, row in df.iterrows():
print row["c1"], row["c2"]
for row in df.itertuples(index=True, name='Pandas'):
print getattr(row, "c1"), getattr(row, "c2")
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)場合、通常のタプルが返されます。
df.iterrows()
を使うべきです。ただし、Seriesオブジェクトを作成する必要があるため、行ごとの繰り返しは特に効率的ではありません。
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
df.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)
次のようにdf.iloc関数を使うことができます。
for i in range(0, len(df)):
print df.iloc[i]['c1'], df.iloc[i]['c2']
私は探していました どのように行と列を反復処理してここで終了しました:
for i, row in df.iterrows():
for j, column in row.iteritems():
print(column)
Q:PandasでDataFrameの行を反復する方法は?
パンダでの繰り返しは反パターンであり、あなたが可能な限り他のすべての選択肢を使い果たしたときにあなたがしたいと思う何かです。あなたは、数千行を超えるものに対して、名前に "iter
"を持つ関数を使うことを考えてはいけません。そうしないと、 lot に慣れる必要があります。
データフレームを印刷しますか。 DataFrame.to_string()
を使用してください。
何か計算したいですか?その場合は、次の順序でメソッドを検索してください( here から変更されたリスト)。
for
ループ)DataFrame.apply()
DataFrame.itertuples()
および iteritems()
DataFrame.iterrows()
iterrows
とitertuples
(どちらもこの質問に対する回答で多数の投票を受けています)は、逐次処理のために行オブジェクト/名前組を生成するなど、非常にまれな状況で使用するべきです。
当局に訴える
ドキュメントページ 繰り返しの際に、次のような大きな赤い警告ボックスが表示されます。
パンダオブジェクトを繰り返し処理するのは一般に遅いです。多くの場合、行を手動で繰り返す必要はありません[...]。
基本的な操作や計算のかなりの数がパンダによって(ベクトル化されて)(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の単純さとスピードによって、あなたは任意に複雑なものをうまく動作させることができます。
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);
dataframe
内のすべての行をループするためにあなたは使うことができます:
for x in range(len(date_example.index)):
print date_example['Date'].iloc[x]
for ind in df.index:
print df['c1'][ind], df['c2'][ind]
時には便利なパターンがあります:
# 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}
dataframe
および各行のの値便利にはを使用)をすべての行でループするには、namedtuples
をndarray
sに変換できます。次に例を示します。
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の最初の要素として追加されます。これはアプリケーションによっては望ましくない場合があります。
値の表示と変更の両方に、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を指定して作業を行うことができます。
さらにスピードアップするために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
なぜ物事を複雑にするのですか?
簡単です。
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']
この例では、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つは、次のとおりです。
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]])