Iterrows pandas получить значение следующих строк
У меня есть df в pandas
import pandas as pd
df = pd.DataFrame(['AA', 'BB', 'CC'], columns = ['value'])
Я хочу перебирать строки в df. Для каждой строки я хочу значение строки s value and next row
Что-то вроде (не работает):
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']
Есть ли более эффективный способ решения этой проблемы?
Ответы
Ответ 1
Во-первых, ваш "грязный путь" в порядке, нет ничего плохого в использовании индексов в dataframe, и это будет не слишком медленным. 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
Второй способ может сделать что-то похожее, чтобы сохранить один индекс в dataframe:
last = df.irow(0)
for i in range(1, df.shape[0]):
print(last)
print(df.irow(i))
last = df.irow(i)
Когда скорость критическая, вы всегда можете попробовать оба и время кода.
Ответ 2
В документе 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
Но я думаю, что строки iter в DataFrame
медленны, если вы можете объяснить, в чем проблема, которую вы хотите решить, может быть, я могу предложить несколько лучших методов.
Ответ 3
Это можно решить также с помощью izip
ping фреймворка данных (итератора) со своей смещенной версией.
Конечно, ошибка индексации не может быть воспроизведена таким образом.
Проверьте это
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
Ответ 4
Я бы использовал функцию 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) Вернуть Numpy-представление DataFrame и вывести значение по значению:
df = df.values
[print(x) for x in df];
производит:
AA
BB
BB
CC
CC