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

Pandas groupby.sum()使用异常:小数据正常大数据结果不符

问题分析与解决方案

首先,你的问题根源在于**new_df["SUM"] = new_df.groupby(["ID"]).sum().reset_index(drop=True)**这一行:当你对ID分组求和后,得到的结果行数是唯一ID的数量,而new_df是explode后的多行数据(每个ID对应多行),直接赋值时Pandas会按索引对齐,这就导致大部分行的SUM值要么是NaN,要么被错误填充。小样本因为数据量小、索引刚好巧合匹配才没暴露问题,大数据量下索引对齐的矛盾就完全显现了。

修正步骤

我们需要用groupby.transform('sum')来替代原有的求和方式,transform会将组内的求和结果广播到该组的每一行,保证结果和原数据行数一致,完美解决索引对齐问题。下面是修正后的完整代码:

import pandas as pd
df = pd.read_excel(r"D:\Tesina\Proteoma Humano\Tablas\uno - copia.xlsx")
# df = pd.DataFrame({'ID': ['C9JLR9','O95391', 'P05114',"P14866"], 'SEQ': ['1..100,182..250,329..417,490..583', '1..100,206..254,493..586', '1..100', "1..100,284..378" ]})

# 替换分隔符并拆分SEQ
df["SEQ"] = df["SEQ"].replace("\.\."," ", regex=True)
new_df = df.assign(SEQ=df.SEQ.str.split(',')).explode('SEQ')

# 计算delta值,去掉冗余循环,一次计算完成
def calculate_delta(x):
    parts = x.split()
    start = int(parts[0])
    end = int(parts[1])
    return (end + 1) - start if start != 1 else (end + 1)

new_df['delta'] = new_df['SEQ'].apply(calculate_delta)

# 关键修正:用transform计算组内求和,保证和原数据行数一致
new_df["SUM"] = new_df.groupby(["ID"])['delta'].transform('sum')

# 最后合并SEQ的逻辑保持不变
df2 = new_df.groupby(["ID","SUM"], sort=False)["SEQ"].apply(lambda x: ','.join(x.astype(str))).reset_index(name="SEQ")

额外优化点

  • 去掉了原代码中的for index, row in df.iterrows()循环:这个循环其实是重复对整个new_df['delta']赋值,完全没必要,直接用apply一次计算即可,效率更高。
  • 明确指定求和的列是delta:原代码中groupby.sum()会对所有数值列求和,虽然这里只有delta,但明确指定列更清晰,避免后续添加列时出错。

这样修改后,不管是小样本还是10471行的大数据,SUM值都会准确对应每个ID的delta总和,且保持原数据行数不变。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 17:32:33