为何Pandas 1.3.2中groupby写入CSV前失效,读写CSV后运行正常?
问题根因
你遇到的异常是Pandas 1.3.0版本的两处不兼容变更共同导致的:
- 空DataFrame追加行时的类型推断逻辑收紧:你初始化
wallet时没有指定列类型,所有列默认是object类型。1.1.5版本追加Series时会自动将数字内容的Cost、Qty列转换为整数类型,而1.3.2版本不会做隐式类型转换,这两列会保持object类型。 - groupby聚合方法的默认参数变更:1.3.0起
groupby.sum()的numeric_only参数默认值从None改为True,只会对明确的数值类型(int/float等)列执行求和,object类型的列会被直接排除,因此最终返回只有索引的空DataFrame。
对应问题解答
1. 两个版本groupby结果不一致的原因
就是上述两处变更共同作用的结果:1.1.5版本中Cost、Qty是数值类型,sum会正常计算;1.3.2版本中这两列是object类型,被sum默认逻辑排除,所以返回空结果。
2. 读写CSV后运行正常的原因
pd.read_csv()会自动根据文件内容推断列类型,Cost、Qty列全为数字,会被自动识别为整数类型,符合sum的默认计算要求,所以结果正常。
3. 内存级替代方案
不需要读写文件,可选用以下任意一种方案:
- 方案一:初始化DataFrame时直接指定列类型,从根源避免object类型问题
wallet = pd.DataFrame(columns=['Data','Ticker','Cost','Qty'], dtype={'Cost': 'int64', 'Qty': 'int64'})
- 方案二:groupby前显式转换数值列类型
wallet[['Cost', 'Qty']] = wallet[['Cost', 'Qty']].astype(int) summary = wallet.groupby(['Ticker']).sum()
- 方案三:sum时显式关闭numeric_only限制(仅确认列内容都是数字时使用)
summary = wallet.groupby(['Ticker']).sum(numeric_only=False)
- 方案四:废弃已淘汰的
append方法,一次性生成DataFrame,自动推断正确类型
rows = [ ['17022019','pcr',10,10], ['12042020','pcr',12,15], ['19012021','peo',8,16] ] wallet = pd.DataFrame(rows, columns=['Data','Ticker','Cost','Qty'])
4. 1.3.2版本groupby的使用注意
你的写法本身没有逻辑错误,只是没有适配版本默认行为的变更:
- 1.3.x版本groupby聚合函数默认只处理明确的数值类型列,避免隐式类型转换导致的不可预期结果
- 除了sum,mean、max、min等聚合函数都做了相同的参数默认值调整
- 额外提个小问题:你的代码里
summary.reset_index()没有赋值,不会修改原summary对象,需要写成summary = summary.reset_index()才能生效。
内容的提问来源于stack exchange,提问作者Rafal
相关产品推荐
相关产品推荐

