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

如何在Polars中高效实现DataFrame行与单行DataFrame的除法?

Polars实现DataFrame与单行DataFrame的高效除法运算

需求描述

需要将Polars DataFrame的每一行与一个单行DataFrame执行除法运算,类似Pandas中的df.divide方法。当前通过重复单行DataFrame至原DataFrame行数再运算的方式,在数据量较大时耗时严重,需要更优实现。

当前低效实现

from itertools import repeat
import polars as pl

data = {'a': [i for i in range(1, 5)],
        'b': [i for i in range(1, 5)],
        'c': [i for i in range(1, 5)],
        'd': [i for i in range(1, 5)]}
df = pl.DataFrame(data)
divisors = pl.DataFrame({'d1': 1, 'd2': 10, 'd3': 100, 'd4': 1000})
divisors_as_big_as_df = pl.concat([item for item in repeat(divisors, len(df))])
divided_df = df / divisors_as_big_as_df

优化方案

方案1:利用Polars自动广播特性(推荐)

Polars支持单行DataFrame与多行DataFrame的自动广播运算,无需手动复制数据。只需确保两个DataFrame的列名一一对应:

import polars as pl

data = {'a': list(range(1,5)), 'b': list(range(1,5)), 'c': list(range(1,5)), 'd': list(range(1,5))}
df = pl.DataFrame(data)
# 调整除数DataFrame的列名与原DataFrame一致
divisors = pl.DataFrame({'a': 1, 'b': 10, 'c': 100, 'd': 1000})
# 直接执行除法,Polars自动广播单行数据至原行数
divided_df = df / divisors

方案2:保留原列名,通过表达式指定对应除数

如果不想修改除数DataFrame的列名,可以提取单行的数值作为常量,结合列表达式批量运算:

import polars as pl

data = {'a': list(range(1,5)), 'b': list(range(1,5)), 'c': list(range(1,5)), 'd': list(range(1,5))}
df = pl.DataFrame(data)
divisors = pl.DataFrame({'d1': 1, 'd2': 10, 'd3': 100, 'd4': 1000})

# 提取单行除数的数值列表
div_values = divisors.row(0)

# 逐个列指定除法运算
divided_df = df.select(
    pl.col('a') / div_values[0],
    pl.col('b') / div_values[1],
    pl.col('c') / div_values[2],
    pl.col('d') / div_values[3]
)

方案3:批量生成表达式(简洁版)

通过列表推导式自动匹配列与对应除数,适合列数较多的场景:

divided_df = df.select(
    [pl.col(col) / divisors.row(0)[idx] for idx, col in enumerate(df.columns)]
)

优化原理

手动复制单行DataFrame会生成大量冗余数据,占用内存且增加IO开销。而Polars的广播机制是逻辑层面的重复,不会实际复制数据,运算时直接将单行数值应用到每一行,效率提升显著。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 11:35:14