每个柱子的不同石斑鱼与熊猫GroupBy

yat*_*atu 8 python group-by pandas pandas-groupby

我怎么能使用多维Grouper,在这种情况下是另一个数据帧,作为另一个数据帧的Grouper?可以一步完成吗?

我的问题主要是关于如何在这些情况下执行实际的分组,但要使其更具体,请说我想接受transform并采取sum.

考虑例如:

df1 = pd.DataFrame({'a':[1,2,3,4], 'b':[5,6,7,8]})

print(df1)
   a  b
0  1  5
1  2  6
2  3  7
3  4  8

df2  = pd.DataFrame({'a':['A','B','A','B'], 'b':['A','A','B','B']})

print(df2)
   a  b
0  A  A
1  B  A
2  A  B
3  B  B
Run Code Online (Sandbox Code Playgroud)

然后,预期的输出将是:

   a  b
0  4  11
1  6  11
2  4  15
3  6  15
Run Code Online (Sandbox Code Playgroud)

凡列abdf1已按列进行分组a,并bdf2分别.

Sco*_*ton 7

尝试使用applylambda函数应用于数据帧的每一列,然后使用该pd.Series的名称按第二个数据帧进行分组:

df1.apply(lambda x: x.groupby(df2[x.name]).transform('sum'))
Run Code Online (Sandbox Code Playgroud)

输出:

   a   b
0  4  11
1  6  11
2  4  15
3  6  15
Run Code Online (Sandbox Code Playgroud)


cs9*_*s95 5

您必须单独对每列进行分组,因为每列使用不同的分组方案.

如果你想要一个更干净的版本,我会建议对列名称进行列表理解,并调用pd.concat结果系列:

pd.concat([df1[c].groupby(df2[c]).transform('sum') for c in df1.columns], axis=1)

   a   b
0  4  11
1  6  11
2  4  15
3  6  15
Run Code Online (Sandbox Code Playgroud)

不是说apply在另一个答案中使用有什么问题,只是我不喜欢apply,所以这是我的建议:-)


以下是您的细读时间.只是为了您的样本数据,您会注意到时间上的差异是显而易见的.

%%timeit 
(df1.stack()
    .groupby([df2.stack().index.get_level_values(level=1), df2.stack()])
    .transform('sum').unstack())
%%timeit 
df1.apply(lambda x: x.groupby(df2[x.name]).transform('sum'))
%%timeit 
pd.concat([df1[c].groupby(df2[c]).transform('sum') for c in df1.columns], axis=1)

8.99 ms ± 4.55 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
8.35 ms ± 859 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)
6.13 ms ± 279 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
Run Code Online (Sandbox Code Playgroud)

不是说apply速度慢,但在这种情况下显式迭代更快.此外,您会注意到,由于迭代次数取决于列数,因此第二次和第三次定时解决方案将以更大的长度v/s宽度进行更好的扩展.