Pandas: сдвинуть значения на одну строку внутри группы
У меня есть кадр данных Pandas, и я хочу создать новый столбец, значения которого соответствуют другому столбцу, сдвинутому на одну строку. В последней строке должно отображаться NaN.
Уловка заключается в том, что я хочу сделать это по группе, причем последняя строка каждой группы показывает NaN. НЕ иметь последнюю строку группы "украсть" значение из группы, которая оказывается смежной в кадре данных.
Моя попытка реализации довольно позорно нарушена, поэтому я явно недопонимаю что-то фундаментальное.
df['B_shifted'] = df.groupby(['A'])['B'].transform(lambda x:x.values[1:])
Ответы
Ответ 1
Shift работает с выходом предложения groupby:
>>> df = pandas.DataFrame(numpy.random.randint(1,3, (10,5)), columns=['a','b','c','d','e'])
>>> df
a b c d e
0 2 1 2 1 1
1 2 1 1 1 1
2 1 2 2 1 2
3 1 2 1 1 2
4 2 2 1 1 2
5 2 2 2 2 1
6 2 2 1 1 1
7 2 2 2 1 1
8 2 2 2 2 1
9 2 2 2 2 1
for k, v in df.groupby('a'):
print k
print 'normal'
print v
print 'shifted'
print v.shift(1)
1
normal
a b c d e
2 1 2 2 1 2
3 1 2 1 1 2
shifted
a b c d e
2 NaN NaN NaN NaN NaN
3 1 2 2 1 2
2
normal
a b c d e
0 2 1 2 1 1
1 2 1 1 1 1
4 2 2 1 1 2
5 2 2 2 2 1
6 2 2 1 1 1
7 2 2 2 1 1
8 2 2 2 2 1
9 2 2 2 2 1
shifted
a b c d e
0 NaN NaN NaN NaN NaN
1 2 1 2 1 1
4 2 1 1 1 1
5 2 2 1 1 2
6 2 2 2 2 1
7 2 2 1 1 1
8 2 2 2 1 1
9 2 2 2 2 1
Ответ 2
Новые версии панд теперь могут выполнять shift
группы:
df['B_shifted'] = df.groupby(['A'])['B'].shift(1)
Обратите внимание, что при переключении вниз, это первый ряд, который имеет NaN.
Ответ 3
Комментарий @EdChum - лучший ответ на этот вопрос, поэтому я размещаю его здесь для потомков:
df['B_shifted'] = df.groupby(['A'])['B'].transform(lambda x:x.shift())
или аналогичным образом
df['B_shifted'] = df.groupby(['A'])['B'].transform('shift')
.
Быстрая нотация, конечно, более гибкая (например, если вы хотите сдвинуть на 2).
Ответ 4
Все вышеприведенные ответы делают ошибку:
shift(1)
- это смещение вверх на одну строку, что является поведением по умолчанию;
shift(-1)
на самом деле о сдвиге вниз на одну строку.
см. пример shift
документации панд