如何在Pandas数据框组中移动一列,然后再联接回单个数据框?

时间:2019-02-22 14:39:36

标签: python pandas dataframe

如果我有这样的数据框:

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方法来实现这一目标?

2 个答案:

答案 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