web-dev-qa-db-ja.com

iterrows pandas次の行の値を取得

私はパンダでdfを持っています

import pandas as pd
df = pd.DataFrame(['AA', 'BB', 'CC'], columns = ['value'])

Dfの行を繰り返したい。行ごとにrows value and next rowsの値が必要です(動作しません):

for i, row in df.iterrows():
     print row['value']
     i1, row1 = next(df.iterrows())
     print row1['value']

結果として欲しい

'AA'
'BB'
'BB'
'CC'
'CC'
*Wrong index error here  

この時点で私はこれを解決するための混乱した方法を持っています

for i in range(0, df.shape[0])
   print df.irow(i)['value']
   print df.irow(i+1)['value']

この問題を解決するより効率的な方法はありますか?

27
Ayrat

まず、あなたの「乱雑な方法」は大丈夫です。データフレームにインデックスを使用しても何も問題はありません。これは遅くなりません。 iterrows()自体はそれほど高速ではありません。

動作する最初のアイデアのバージョンは次のとおりです。

row_iterator = df.iterrows()
_, last = row_iterator.next()  # take first item from row_iterator
for i, row in row_iterator:
    print(row['value'])
    print(last['value'])
    last = row

2番目の方法では、1つのインデックスをデータフレームに保存するために、同様のことができます。

last = df.irow(0)
for i in range(1, df.shape[0]):
    print(last)
    print(df.irow(i))
    last = df.irow(i)

速度が重要な場合は、常にコードの両方を試して時間を計ることができます。

19
alisdt

itertoolsドキュメントにはpairwise()関数の例があります:

from itertools import tee, izip
def pairwise(iterable):
    "s -> (s0,s1), (s1,s2), (s2, s3), ..."
    a, b = tee(iterable)
    next(b, None)
    return izip(a, b)

import pandas as pd
df = pd.DataFrame(['AA', 'BB', 'CC'], columns = ['value'])

for (i1, row1), (i2, row2) in pairwise(df.iterrows()):
    print i1, i2, row1["value"], row2["value"]

出力は次のとおりです。

0 1 AA BB
1 2 BB CC

しかし、DataFrameの行が遅いと思います。解決したい問題を説明できれば、もっと良い方法を提案できます。

10
HYRY

次のようにshift()関数を使用します。

df['value_1'] = df.value.shift(-1)
[print(x) for x in df.T.unstack().dropna(how = 'any').values];

生産する

AA
BB
BB
CC
CC

上記のコードの仕組みは次のとおりです。

手順1)シフト機能を使用する

df['value_1'] = df.value.shift(-1)
print(df)

生産する

value value_1
0    AA      BB
1    BB      CC
2    CC     NaN

ステップ2)転置:

df = df.T
print(df)

生成するもの:

          0   1    2
value    AA  BB   CC
value_1  BB  CC  NaN

ステップ3)アンスタック:

df = df.unstack()
print(df)

生成するもの:

0  value       AA
   value_1     BB
1  value       BB
   value_1     CC
2  value       CC
   value_1    NaN
dtype: object

ステップ4)NaN値をドロップする

df = df.dropna(how = 'any')
print(df)

生成するもの:

0  value      AA
   value_1    BB
1  value      BB
   value_1    CC
2  value      CC
dtype: object

ステップ5)DataFrameのNumpy表現を返し、値ごとに値を出力します。

df = df.values
[print(x) for x in df];

生成するもの:

AA
BB
BB
CC
CC
3
Anna K.

これは、データフレーム(イテレータ)をそれ自体のオフセットバージョンでizippingすることでも解決できます。

もちろん、インデックス作成エラーはこの方法では再現できません。

これをチェックしてください

import pandas as pd
from itertools import izip

df = pd.DataFrame(['AA', 'BB', 'CC'], columns = ['value'])   

for id1, id2 in izip(df.iterrows(),df.ix[1:].iterrows()):
    print id1[1]['value']
    print id2[1]['value']

与える

AA
BB
BB
CC
2
Acorbe

回答の組み合わせにより、実行時間が非常に短縮されました。 shiftメソッドを使用して次の行の値の新しい列を作成し、その後@alisdtのようにrow_iterator関数を使用しますが、ここではiterrowsから変更しました= to itertuplesこれは100倍高速です。

私のスクリプトは、異なる長さの複製のデータフレームを反復し、複製ごとに1秒を追加して、すべてが一意になるようにします。

# create new column with shifted values from the departure time column
df['next_column_value'] = df['column_value'].shift(1)
# create row iterator that can 'save' the next row without running for loop
row_iterator = df.itertuples()
# jump to the next row using the row iterator
last = next(row_iterator)
# because pandas does not support items alteration i need to save it as an object
t = last[your_column_num]
# run and update the time duplications with one more second each
for row in row_iterator:
    if row.column_value == row.next_column_value:
         t = t + add_sec
         df_result.at[row.Index, 'column_name'] = t
    else:
         # here i resetting the 'last' and 't' values
         last = row
         t = last[your_column_num]

それが役立つことを願っています。

0
R.V