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

Python Pandas聚合DataFrame:求和全为NaN时返回NaN而非0

Pandas分组求和:全NaN列返回NaN而非0

问题背景

我在Python Pandas中有如下DataFrame:

输入数据:

import numpy as np
import pandas as pd

df = pd.DataFrame({
    'id' : [999, 999, 999, 185, 185, 185, 999, 999, 999],
    'target' : [1, 1, 1, 0, 0, 0, 1, 1, 1],
    'event': ['2023-01-01', '2023-01-01', '2023-02-03', '2023-01-01', '2023-01-02', '2023-01-03', '2023-01-01', '2023-01-02', '2023-01-03'],
    'survey': ['2023-02-02', '2023-02-02', '2023-02-02', '2023-03-10', '2023-03-10', '2023-03-10', '2023-04-22', '2023-04-22', '2023-04-22'],
    'event1': [1, 6, 11, 16, np.nan, 22, 74, 109, 52],
    'event2': [2, 7, np.nan, 17, 22, np.nan, np.nan, 10, 5],
    'event3': [3, 8, 13, 18, 23, np.nan, 2, np.nan, 99],
    'event4': [4, 9, np.nan, np.nan, np.nan, 11, 8, np.nan, np.nan],
    'event5': [np.nan, np.nan, 15, 20, 25, 1, 1, 3, np.nan]
})

观察数据可知,当id=999且event='2023-01-01'时,event5列存在2个NaN值。

需求:
按id、target、survey、event分组,对event1至event5列求和;当分组内某列全为NaN时,求和结果返回NaN而非默认的0。

现有代码执行后,全NaN列的求和结果为0,不符合需求:

column_names = df.columns
df = df.groupby(["id","target", "survey", "event"]).agg({col: 'sum' for col in column_names if col not in ["id","target", "survey", "event"]})
df.reset_index(inplace = True)

解决方案

方法1:利用sum的min_count参数

Pandas的sum方法内置min_count参数,可指定返回有效求和结果所需的最小非NaN值数量。设置min_count=1时,若分组内该列无有效数值(全NaN),则返回NaN。

修改后的代码:

# 筛选需要聚合的列
agg_columns = [col for col in df.columns if col not in ["id", "target", "survey", "event"]]

# 分组聚合,为每个列指定带min_count的sum逻辑
df_result = df.groupby(["id", "target", "survey", "event"]).agg(
    {col: lambda x: x.sum(min_count=1) for col in agg_columns}
).reset_index()

方法2:自定义聚合函数

如果需要更灵活的判断逻辑,可以自定义函数,先检查分组内是否全为NaN,再决定返回值:

import numpy as np

def sum_keep_nan(col):
    # 检查列是否全为NaN
    if col.isna().all():
        return np.nan
    # 否则返回求和结果
    return col.sum()

agg_columns = [col for col in df.columns if col not in ["id", "target", "survey", "event"]]

df_result = df.groupby(["id", "target", "survey", "event"]).agg(
    {col: sum_keep_nan for col in agg_columns}
).reset_index()

效果验证

以id=999、survey='2023-02-02'、event='2023-01-01'的分组为例:

  • event5列有2个NaN和1个有效值15,求和结果为15(符合预期);
  • 若某分组内某列全为NaN,求和结果会返回NaN而非0。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:33:25