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

Python Polars中.over操作结果不一致问题求助

Polars按ID分组替换日期后缺失值统计结果不稳定的解决办法

问题分析

你当前的代码df.select(pl.col('date').min().over('id'))['date'].is_null().sum()出现结果不一致的问题,大概率和以下两点有关:

  • 若你的数据是LazyFrame,每次执行select都会重新触发执行计划,部分版本的Polars在并行处理大表窗口函数时,可能因缓存或计算逻辑的微小差异导致结果波动;
  • 窗口函数min().over('id')在处理全null的ID分组时,部分旧版本Polars存在计算不稳定的bug。

而Pandas的transform方法在分组处理时逻辑更稳定,能准确统计出全null分组的总行数(即你得到的29436)。

解决方案

方案1:改用分组聚合统计(最稳定)

先按ID分组统计最小日期和对应行数,再筛选出最小日期为null的分组,求和得到总行数:

# 分组计算每个ID的最小日期及行数
id_summary = df.group_by('id').agg(
    pl.col('date').min().alias('min_date'),
    pl.count().alias('row_count')
)
# 统计全null分组的总行数
correct_null_count = id_summary.filter(pl.col('min_date').is_null())['row_count'].sum()

这种方式绕开了窗口函数的潜在问题,计算逻辑更直观,结果也更稳定。

方案2:优化窗口函数写法并确保数据是EagerFrame

如果坚持用窗口函数,先将LazyFrame转为EagerFrame(即collect()),再添加列后统计:

# 确保数据已加载为内存中的DataFrame
if isinstance(df, pl.LazyFrame):
    df = df.collect()
# 添加替换后的日期列
df = df.with_columns(pl.col('date').min().over('id').alias('replaced_date'))
# 统计缺失行数
null_count = df['replaced_date'].is_null().sum()

方案3:升级Polars到最新版本

部分旧版本Polars的窗口函数在处理大表null值时存在bug,升级到最新稳定版(比如>=0.20.0)大概率能解决结果不一致的问题:

pip install --upgrade polars

验证方法

你可以用方案1的分组统计结果和Pandas的结果对比,确认29436这个值的准确性,再用这个结果验证其他方法的输出是否一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 02:18:25