我想对列 idx 进行分组,然后将列 val 转移,并在最后一行保留 idx 。
import pandas as pd
df = pd.DataFrame({'idx':['a','a','b','b'],
'val':['a1','a2','b1','b2']})
df
idx val
0 a a1
1 a a2
2 b b1
3 b b2
我尝试了df['val_shift'] = df.groupby('idx').val.shift(1)
idx val val_shift
0 a a1 NaN
1 a a2 a1
2 b b1 NaN
3 b b2 b1
但是我想要。
idx val
0 a NaN
1 a a1
2 a a2
3 b NaN
4 b b1
5 b b2
有没有办法得到这个?
答案 0 :(得分:4)
我相信您需要concat
提取的drop_duplicates
最后一行具有更改索引值才能首先正确排序,因为shift
总是在这里删除最后一个值:
df1 = df.drop_duplicates('idx', keep='last')
df1.index += .5
df = pd.concat([df, df1]).sort_index().reset_index(drop=True)
替代解决方案:
df = df.drop_duplicates('idx', keep='last').append(df).sort_index().reset_index(drop=True)
df['val_shift'] = df.groupby('idx').val.shift(1)
print (df)
idx val val_shift
0 a a1 NaN
1 a a2 a1
2 a a2 a2
3 b b1 NaN
4 b b2 b1
5 b b2 b2
如果要删除val
之后的shift
,请使用pop
和语法糖-按系列df['idx']
进行分组:
df['val_shift'] = df.pop('val').groupby(df['idx']).shift(1)
print (df)
idx val_shift
0 a NaN
1 a a1
2 a a2
3 b NaN
4 b b1
5 b b2
答案 1 :(得分:4)
在我看来,您只是在每个仅填充'idx'
的组的前面插入一个空的数据框。
pd.concat([
d[['idx']].head(1).append(d)
for _, d in df.groupby('idx')
], ignore_index=True)
idx val
0 a NaN
1 a a1
2 a a2
3 b NaN
4 b b1
5 b b2
替代
df[['idx']].drop_duplicates('idx').append(df).sort_values('idx').reset_index(drop=True)
答案 2 :(得分:3)
将concat
与tail
一起使用
newdf=pd.concat([df,df.groupby('idx').tail(1)])
newdf=newdf.assign(val=newdf.groupby('idx').shift()).sort_index()
newdf
Out[885]:
idx val
0 a NaN
1 a a1
1 a a2
2 b NaN
3 b b1
3 b b2