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

Polars透视表求和时将空值视为0的问题及解决咨询

解决Polars透视表聚合时保留Null的问题

问题分析

你遇到两个核心问题:

  1. 默认sum聚合会忽略Null值,导致分组内存在Null时仍返回非Null的求和结果(如AA-EU分组有一个Null,但返回1.5);全Null分组返回0.0(如BB-US),不符合"有Null则显示Null"的需求。
  2. 自定义lambda函数报错AttributeError: 'function' object has no attribute '_pyexpr',因为Polars的pivot方法的aggregate_function参数要求传入Polars表达式(pl.Expr),而非普通Python函数。

解决方案

方法1:直接使用表达式作为聚合函数

通过pl.when().then().otherwise()构建聚合逻辑,判断分组内是否存在Null,再决定返回Null还是求和结果:

import polars as pl

df = pl.DataFrame({
    'label':   ['AA', 'CC', 'BB', 'AA', 'CC'],
    'account': ['EU', 'US', 'US', 'EU', 'EU'],
    'qty':     [1.5,  43.2, None, None, 18.9]
})

# 构建聚合表达式:分组内有Null则返回Null,否则返回sum
agg_expr = pl.when(pl.col("qty").is_null().any()).then(None).otherwise(pl.col("qty").sum())

# 执行透视表
result = df.pivot(
    values='qty',
    index='label',
    columns='account',
    aggregate_function=agg_expr
)

print(result)

方法2:先分组聚合再转透视表(兼容旧版Polars)

如果你的Polars版本不支持直接给pivot传表达式,可先通过group_by完成聚合逻辑,再转成透视表:

import polars as pl

df = pl.DataFrame({
    'label':   ['AA', 'CC', 'BB', 'AA', 'CC'],
    'account': ['EU', 'US', 'US', 'EU', 'EU'],
    'qty':     [1.5,  43.2, None, None, 18.9]
})

# 先分组聚合
agg_df = df.group_by(['label', 'account']).agg(
    pl.when(pl.col("qty").is_null().any()).then(None).otherwise(pl.col("qty").sum()).alias('qty')
)

# 转成透视表
result = agg_df.pivot(values='qty', index='label', columns='account')

print(result)

预期输出

两种方法都会得到符合需求的结果:

shape: (3, 3)
┌───────┬──────┬──────┐
│ label ┆ EU   ┆ US   │
│ ---   ┆ ---  ┆ ---  │
│ str   ┆ f64  ┆ f64  │
╞═══════╪══════╪══════╡
│ AA    ┆ null ┆ null │
│ CC    ┆ 18.9 ┆ 43.2 │
│ BB    ┆ null ┆ null │
└───────┴──────┴──────┘

内容的提问来源于stack exchange,提问作者Phil-ZXX

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:25:12