我有一个Pandas数据帧,我想创建一个新列,其值是另一列的值,向下移动一行。最后一行应显示NaN。
问题是我想按组进行此操作,每组的最后一行显示NaN。不要让一个组的最后一行“窃取”一个恰好在数据框中相邻的组中的值。
我的尝试实施得非常可耻,所以我显然误解了一些基本的东西。
df['B_shifted'] = df.groupby(['A'])['B'].transform(lambda x:x.values[1:])
答案 0 :(得分:44)
新版本的pandas现在可以在群组上执行shift
:
df['B_shifted'] = df.groupby(['A'])['B'].shift(1)
请注意,在移动 down 时,它是具有NaN的第一个行。
答案 1 :(得分:15)
@ EdChum的评论对这个问题是一个更好的答案,所以我在这里发帖给后人:
df['B_shifted'] = df.groupby(['A'])['B'].transform(lambda x:x.shift())
或类似地
df['B_shifted'] = df.groupby(['A'])['B'].transform('shift')
。
当然,前一种符号更灵活(例如,如果你想换2)。
答案 2 :(得分:9)
Shift适用于group by子句的输出:
>>> 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
答案 3 :(得分:0)