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

如何在Python Polars中通过单次函数调用为DataFrame添加多列?

Polars生成多列时减少函数重复调用的方法

现有代码为DataFrame添加count_of_10和count_of_12两列时,每行都会调用两次uses_object函数,效率较低。想优化成每行仅调用一次该函数。

原实现代码:

import polars as pl

df = pl.DataFrame({
    'x': [11, 22],
})

def uses_object(x):
    r = list(range(0, x))
    c10 = r.count(10)
    c12 = r.count(12)
    return c10, c12

df = df.with_columns(
    count_of_10 = pl.col('x').map_elements(lambda x: uses_object(x)[0]),
    count_of_12 = pl.col('x').map_elements(lambda x: uses_object(x)[1]),
)

print(df)

尝试直接多赋值的写法会报错:

df = df.with_columns(
    count_of_10, count_of_12 = uses_object(pl.col('x')),
)

报错信息:

NameError
name 'count_of_10' is not defined.

方案1:返回结构体并展开

让uses_object返回字典形式的结构体,通过map_elements一次性生成包含两个字段的结构体列,再展开成独立列。这样每行只会调用一次uses_object:

import polars as pl

df = pl.DataFrame({
    'x': [11, 22],
})

def uses_object(x):
    r = list(range(0, x))
    c10 = r.count(10)
    c12 = r.count(12)
    return {'count_of_10': c10, 'count_of_12': c12}

df = df.with_columns(
    pl.col('x').map_elements(
        uses_object, 
        return_dtype=pl.Struct([
            pl.Field('count_of_10', pl.Int64),
            pl.Field('count_of_12', pl.Int64)
        ])
    ).alias('temp')
).unnest('temp')

print(df)

输出结果和原代码一致,但uses_object每行仅执行一次。

方案2:用元组+结构体简化

如果不想修改uses_object的返回格式,保持返回元组,用pl.struct包装后展开,再重命名字段即可:

import polars as pl

df = pl.DataFrame({
    'x': [11, 22],
})

def uses_object(x):
    r = list(range(0, x))
    c10 = r.count(10)
    c12 = r.count(12)
    return c10, c12

df = df.with_columns(
    pl.struct(
        pl.col('x').map_elements(uses_object, return_dtype=pl.Tuple([pl.Int64, pl.Int64]))
    ).alias('temp')
).unnest('temp').rename({'field_0': 'count_of_10', 'field_1': 'count_of_12'})

print(df)

方案3:apply逐行处理(小数据集适用)

如果数据集不大,也可以用apply方法,每行处理一次并返回多列:

import polars as pl

df = pl.DataFrame({
    'x': [11, 22],
})

def uses_object(row):
    x = row['x']
    r = list(range(0, x))
    c10 = r.count(10)
    c12 = r.count(12)
    return pl.Series([c10, c12], name=['count_of_10', 'count_of_12'])

df = df.apply(uses_object, return_dtype=pl.Struct)

print(df)

注意:apply是逐行处理,性能不如向量化操作,仅适合小数据场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 20:55:32