You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Polars DataFrame各列除以另一DataFrame的对应列标量

Polars中按列对应标量完成逐元素除法的最优实现

我是Polars新手,现在需要处理一个场景:有一个m×n的Polars DataFrame(df),还有一个1×n的Polars DataFrame(scalars),要求把df的每一列,对应除以scalars中同列的那个标量值。

示例数据代码

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)

df的输出

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 │
└─────┴─────┴─────┘

scalars的输出

shape: (1, 3)
┌─────┬─────┬─────┐
│ a   ┆ b   ┆ c   │
│ --- ┆ --- ┆ --- │
│ f64 ┆ f64 ┆ f64 │
╞═════╪═════╪═════╡
│ 1.0 ┆ 2.0 ┆ 3.0 │
└─────┴─────┴─────┘

已有实现方式

Pandas+NumPy广播实现

我用Pandas结合NumPy广播可以轻松实现需求:

df.to_pandas() / scalars.to_numpy()

输出:

a    b    c
0  1.0  1.0  1.0
1  4.0  2.5  2.0
2  7.0  4.0  3.0

自行想到的Polars合并运算

我尝试通过合并两个DataFrame后运算:

(pl.concat([df, scalars])
 .with_columns(pl.all() / pl.all().tail(1))
 .head(-1))

输出:

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 │
└─────┴─────┴─────┘

Polars原生最优实现方法

方法1:利用Polars自动广播特性直接运算

Polars支持维度兼容的自动广播,scalars是1行n列,df是m行n列,直接做除法即可,Polars会自动把scalars的行广播到df的所有行:

result = df / scalars

输出和预期完全一致,代码简洁且性能最优。

方法2:提取标量值逐列运算

如果需要更明确地控制列对应关系,可以提取scalars中每列的单个值,对df的对应列做除法:

result = df.select([
    pl.col(col) / scalars[col].item() 
    for col in df.columns
])

这种方式逻辑直观,适合需要单独处理部分列的场景,性能与广播方法接近。

方法3:显式广播后运算

可以把scalars显式广播到和df相同的行数,再做除法,适合需要明确广播步骤的场景:

result = df / scalars.with_row_count().drop("row_nr").broadcast_to(df.shape)

内容的提问来源于stack exchange,提问作者HavelTheGreat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 18:51:08