2017-07-26 69 views
2

我有一个数据帧连续下一个值到新的柱熊猫数据帧

id value 
v1  100 
v1  200 
v1  300 
v1  400 
v2  500 
v2  600 
v2  700 
v3  800 
v3  900 

我期待变换数据帧到新的数据帧DF2:

id val1 val2 
v1  100  200 
v1  200  300 
v1  300  400 
v1  400  100 
v2  500  600 
v2  600  700 
v2  700  500 
v3  800  900 
v3  900  800 

即移在下一列中的下一个连续的值和也有种按ID编组,

我试过使用df.shift(),但没有工作。

除此之外还有其他的选择吗?

回答

4

我们想用np.roll到组内完成任务。通过使用transform,我们绕过了组内索引。

df.groupby('id').value.transform(np.roll, shift=-1) 

0 200 
1 300 
2 400 
3 100 
4 600 
5 700 
6 500 
7 900 
8 800 
Name: value, dtype: int64 

我们可以到df副本添加一个新列assign

df.assign(val2=df.groupby('id').value.transform(np.roll, shift=-1)) 

    id value val2 
0 v1 100 200 
1 v1 200 300 
2 v1 300 400 
3 v1 400 100 
4 v2 500 600 
5 v2 600 700 
6 v2 700 500 
7 v3 800 900 
8 v3 900 800 

或者直接在地方增加df新列

df['val2'] = df.groupby('id').value.transform(np.roll, shift=-1) 

df 

    id value val2 
0 v1 100 200 
1 v1 200 300 
2 v1 300 400 
3 v1 400 100 
4 v2 500 600 
5 v2 600 700 
6 v2 700 500 
7 v3 800 900 
8 v3 900 800 
+0

先生,我的id列不是整数类型,请参阅我编辑的数据框。虽然运行df.groupby()值,你的第一行代码,我得到的错误:'“DataFrameGroupBy”对象有没有属性“value'' – Shubham

+0

@SRingne,不应该影响结果的。该错误表明名为“value”的列不在“df”中。请证实它是否是。 – piRSquared

+0

工作!其实我拼错列名!万分感谢! – Shubham

4

我想你需要numpy.roll

df['val2'] = df.groupby('id')['value'].apply(lambda x: pd.Series(np.roll(x, -1))).values 
print (df) 
    id value val2 
0 1 100 200 
1 1 200 300 
2 1 300 400 
3 1 400 100 
4 2 500 600 
5 2 600 700 
6 2 700 500 
7 3 800 900 
8 3 900 800 
+0

id列不是一个整数。请参阅编辑。 我收到错误:'与帧索引插入列的不兼容索引' – Shubham

+0

嗯,如果有值到底它不起作用? – jezrael

+0

先生它给出了上面提到的错误。 '型(DF [ 'ID'] [0])= 'STR' 和类型(DF [ '值'] [0])= numpy.int64' – Shubham