Polars noob,给定一个m x n
Polars 数据帧df
和一个1 x n
标量的 Polars 数据帧,我想将每一列除以df
另一帧中相应的标量。
import numpy as np
import polars as pl
cols = list('abc')
df = pl.DataFrame(np.linspace(1, 9, 9).reshape(3, 3),
schema=cols)
scalars = pl.DataFrame(np.linspace(1, 3, 3)[:, None],
schema=cols)
In [13]: df
Out[13]:
shape: (3, 3)
┌─────┬─────┬─────┐
│ a ┆ b ┆ c │
│ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 │
╞═════╪═════╪═════╡
│ 1.0 ┆ 2.0 ┆ 3.0 │
│ 4.0 ┆ 5.0 ┆ 6.0 │
│ 7.0 ┆ 8.0 ┆ 9.0 │
└─────┴─────┴─────┘
In [14]: scalars
Out[14]:
shape: (1, 3)
┌─────┬─────┬─────┐
│ a ┆ b ┆ c │
│ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 │
╞═════╪═════╪═════╡
│ 1.0 ┆ 2.0 ┆ 3.0 │
└─────┴─────┴─────┘
我可以在 Pandas 中轻松完成此任务,如下所示,通过委托 NumPy 广播,但我想知道最好的方法是什么,而无需在 Polars / Pandas 表示之间来回切换。
In [16]: df.to_pandas() / scalars.to_numpy()
Out[16]:
a b c
0 1.0 1.0 1.0
1 4.0 2.5 2.0
2 7.0 4.0 3.0
我发现了这个类似的问题,其中标量常量已经是原始帧中的一行,但不知道如何利用另一个帧中的行。
到目前为止我能想到的最好的办法就是组合框架并做一些......看起来很讨厌的事情:D
In [31]: (pl.concat([df, scalars])
...: .with_columns(pl.all() / pl.all().tail(1))
...: .head(-1))
Out[31]:
shape: (3, 3)
┌─────┬─────┬─────┐
│ a ┆ b ┆ c │
│ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 │
╞═════╪═════╪═════╡
│ 1.0 ┆ 1.0 ┆ 1.0 │
│ 4.0 ┆ 2.5 ┆ 2.0 │
│ 7.0 ┆ 4.0 ┆ 3.0 │
└─────┴─────┴─────┘
我认为你找到了一个非常独特/有趣且聪明的解决方案。还可以考虑迭代列:
或者
或者
我不确定这不可能,但我尝试过,如果你将框架调整为相同的形状,简单的算术实际上是有效的。首先,使用
Expr.repeat_by()
然后Expr.list.explode()
列出行:另外,显然您可以在
DataFrame()
和之间使用算术运算Series()
,但似乎您需要transpose()
在DataFrame
执行此操作之前进行操作,因为它是按列完成的( 的第一列DataFrame
除以 的第一个值Series
,依此类推):我已经在更大的 DataFrame 上快速测试了性能,并且所有建议的解决方案在速度上似乎都相似(在我的机器上):