我正在从熊猫过渡,所以请原谅我的非并行大脑。假设我们有如下的pandas代码:
dfx = pd.DataFrame({val:np.random.randint(1,5,100) for val in ['a','b','c','d','x','y','z']})
(
dfx
.groupby('a')
.apply(
lambda df:
df
.sort_values('c')
.groupby('d')
[['x','y','z']]
.agg(['max','mean','median'])
)
)
输出(用平滑的多索引粘贴在这里):
<表类>d 0 1 2 3 4 5 6 7 8 tbody><<tr>x x x y y y z z z 和 是 中值和 是 中值和 是 中值 11 15.0 3.75 4.0 12.0 3.0 3.5 12.0 3.0 3.0 12 9.0 3.0 3.0 5.0 1.666667 1.0 9.0 3.0 4.0 13 33.0 3.0 3.0 30.0 2.727273 3.0 27.0 2.454545 2.0 14 23.0 2.8750 3.0 16.0 2.0 2.0 15.0 1.8750 1.0 21 18.0 2.571429 2.0 13.0 1.857143 2.0 18.0 2.571429 3.0 22 18.0 2.0 1.0 23.0 2.555556 2.0 25.0 2.777778 3.0 23 11.0 3.666667 4.0 9.0 3.0 3.0 9.0 3.0 4.0 24 3.0 1.50 1.50 6.0 3.0 3.0 4.0 2.0 2.0 3 1 28.0 2.80 3.0 21.0 2.10 2.0 29.0 2.90 3.0 3 2 13.0 2.166667 2.0 19.0 3.166667 3.0 18.0 3.0 3.0 3 3 16.0 1.777778 2.0 22.0 2.444444 3.0 32.0 3.555556 4.0 3 4 20.0 2.222222 2.0 23.0 2.555556 2.0 23.0 2.555556 3.0 41 9.0 2.250 2.0 10.0 2.50 2.50 5.0 1.250 1.0 42 19.0 3.166667 3.0 8.0 1.333333 1.0 22.0 3.666667 4.0 43 10.0 2.0 1.0 14.0 2.80 3.0 15.0 3.0 3.0 44 9.0 2.250 2.0 12.0 3.0 3.0 10.0 2.50 2.50 表类>
从你问题的后半部分开始,我认为polar处理子数据框架的方法是使用over
来窗口:
dfplx = pl.DataFrame(dfx)
dfplx.select([
'a', 'b',
pl.col(["x", "y", "z"]).sort_by('c').over(['a', 'd']),
pl.col("x").sort_by('c').mean().over(['a', 'd'].alias("x mean")
])
如果你想在windows中使用apply,这是完全可能的(.list()
使polar期望从lambda得到多个结果):
dfplx.select([
'a', 'b', 'c',
pl.col(['x', 'y', 'z'])
.sort_by('c')
.apply(lambda x: [x.mean(), x.median(), x.max()])
.list()
.over(['a', 'd'])
])
对于完整的翻译,我发现最简洁的方法是简单地生成您想要的列列表:
dfplx.select(['a', 'b'] +
[pl.col(a)
.sort_by('c') # sort for some reason ;)
.apply(func) # apply the [max, mean, median] function
.over(['a', 'd']) # window by a then d
.alias(f"{a} {label}") # rename the result
for a in ['x', 'y', 'z']
for label, func in [("max", pl.max), ("mean", pl.mean), ("median", pl.median)]
])