如果我有这样的数据框:
category name index
A A11 1
A A12 1
A A13 1
A A21 2
A A22 2
A A23 2
...
B B11 1
B B21 2
...
我想首先按类别和索引对数据框进行分组,然后在每个组内将name
列按索引值进行移位(反向移位)-1。
结果将是:
category name index
A A11 1 # Do not shift anything because index is 1
A A12 1
A A13 1
A A22 2 # Shift -1 for anything in (A, 2) group because index here is 2
A A23 2
A A24 2
...
B B11 1
B NA 2 # at the end of each group it should be NA
我尝试过使用.groupby()然后使用.apply(),但是似乎没有简单的方法可以将结果连接回数据框。看来apply方法只能返回一个序列。我该如何使用apply方法来实现这一目标?
答案 0 :(得分:1)
如果我理解您的问题
l=[y.assign(name=y.name.shift(-x[1]+1).values) for x , y in df.groupby(['category','index'])]
Newdf=pd.concat(l)
Newdf
Out[644]:
category name index
0 A A11 1
1 A A12 1
2 A A13 1
3 A A23 2
4 A A24 2
5 A NaN 2
答案 1 :(得分:0)
如果我理解正确,我认为您可以执行此操作的一种方式:
给出df,
category name index
0 A A11 1
1 A A12 1
2 A A13 1
3 A A21 2
4 A A22 2
5 A A23 2
6 B B11 1
7 B B21 2
使用查询来过滤索引不为1的位置,然后在groupby
内移动并合并索引等于1的过滤器数据框的一部分到已移动的数据框。
df_shifted = (df.query("index > 1").groupby(['category','index'])
.apply(lambda x: x['name'].shift(-1))
.reset_index().set_index('level_2').rename_axis(None))
df_out = pd.concat([df_shifted, df.query("index == 1")], sort=False).sort_index()
df_out
输出:
category index name
0 A 1 A11
1 A 1 A12
2 A 1 A13
3 A 2 A22
4 A 2 A23
5 A 2 NaN
6 B 1 B11
7 B 2 NaN