Pandas中GroupBy合并含NaN列触发TypeError的解决方法
问题描述
我有如下DataFrame,需要合并["Area (ha)", "Yield (tn per ha)", "Production (tn)"]三列以消除NaN值。数据示例如下:
Country Crop Season Year Area Yield Production 0 Argentina maize 1 2000 3088715 22 Argentina maize 1 2000 3088715 44 Argentina maize 1 2000 3088715 66 Argentina maize 1 2000 3088715 88 Argentina maize 1 2000 3088715 110 Argentina maize 1 2000 3088715 132 Argentina maize 1 2000 3088715 154 Argentina maize 1 2000 3088715 176 Argentina maize 1 2000 3088715 198 Argentina maize 1 2000 3088715 220 Argentina maize 1 2000 3088715 242 Argentina maize 1 2000 3088715 264 Argentina maize 1 2000 3088715 8754 Argentina maize 1 2000 5.433 8776 Argentina maize 1 2000 5.433 8798 Argentina maize 1 2000 5.433 8820 Argentina maize 1 2000 5.433 8842 Argentina maize 1 2000 5.433 8864 Argentina maize 1 2000 5.433 8886 Argentina maize 1 2000 5.433 8908 Argentina maize 1 2000 5.433 8930 Argentina maize 1 2000 5.433 8952 Argentina maize 1 2000 5.433 8974 Argentina maize 1 2000 5.433 8996 Argentina maize 1 2000 5.433 9018 Argentina maize 1 2000 5.433 17508 Argentina maize 1 2000 16780650 17530 Argentina maize 1 2000 16780650 17552 Argentina maize 1 2000 16780650 17574 Argentina maize 1 2000 16780650 17596 Argentina maize 1 2000 16780650 17618 Argentina maize 1 2000 16780650 17640 Argentina maize 1 2000 16780650 17662 Argentina maize 1 2000 16780650 17684 Argentina maize 1 2000 16780650 17706 Argentina maize 1 2000 16780650 17728 Argentina maize 1 2000 16780650 17750 Argentina maize 1 2000 16780650 17772 Argentina maize 1 2000 16780650
我尝试执行如下代码:
df.groupby(["Country", "Crop", "Season", "Year"], dropna=False).mean().reset_index()
但触发错误:
*** TypeError: agg function failed [how->mean,dtype->object]
期望得到的输出结果为:
Country Crop Season Year Area Yield Production Argentina maize 1 2000 3088715 5.433 16780650
解决方案
错误原因
报错的核心是数值列(Area、Yield、Production)为object类型,无法直接计算均值;同时你的需求是合并同组内的非空值,用mean()并不适配——同组内每个数值列的非空值都是唯一的,应该提取该值而非计算均值。
解决步骤
方法一:转换列类型后提取非空值
- 先将数值列转为数值类型(自动将空值转为NaN):
import pandas as pd df[["Area", "Yield", "Production"]] = df[["Area", "Yield", "Production"]].apply(pd.to_numeric, errors="coerce")
- 分组后取每列的第一个非空值(同组内该列非空值一致,
first()/max()/min()都能得到正确结果):
result = df.groupby(["Country", "Crop", "Season", "Year"], dropna=False).first().reset_index()
方法二:用agg()指定处理逻辑
如果需要更明确的控制,可针对每列写提取逻辑:
df[["Area", "Yield", "Production"]] = df[["Area", "Yield", "Production"]].apply(pd.to_numeric, errors="coerce") result = df.groupby(["Country", "Crop", "Season", "Year"], dropna=False).agg( Area=("Area", lambda x: x.dropna().iloc[0]), Yield=("Yield", lambda x: x.dropna().iloc[0]), Production=("Production", lambda x: x.dropna().iloc[0]) ).reset_index()
补充说明
转换为数值类型后,虽然可以用mean()得到结果,但first()更高效且贴合需求——毕竟同组内该列的非空值都是同一个数,均值等于该数,但提取非空值的逻辑更直接。
内容的提问来源于stack exchange,提问作者user308827
相关产品推荐
相关产品推荐

