GroupBy后对各列应用不同函数时first()报错的原因排查
问题原因及解决方案
这个坑我刚踩过不久!你遇到的错误核心是两种first()方法完全不是一回事,别被同名给坑了:
为什么会报错?
- 当你直接调用
groupby(['S','id', 'lane', 'timestamp','E']).first()时,这里的first()是pandas GroupBy对象的内置方法,作用是提取每组中第一个非缺失值,不需要额外参数,所以能正常运行。 - 但在自定义函数
f(x)里,x['b']是一个Series对象,而Series.first()是时间序列专属方法——它需要传入一个offset参数(比如'1H'、'3D'),用来筛选时间序列中前N个时间周期的数据,和GroupBy的first()功能完全无关!所以你没传参数就会触发TypeError。
解决方法(推荐从优到次)
1. 用agg()替代apply()(最简洁高效)
完全没必要用自定义apply,pandas的agg()方法直接支持为不同列指定不同聚合函数,代码更简洁,执行效率也更高(apply是逐组遍历,agg是向量化操作):
require_data = required_data.groupby(['S','id', 'lane', 'timestamp','E']).agg( a=('a', 'max'), b=('b', 'first'), # 这里的'first'就是GroupBy的first方法,和直接调用groupby.first()逻辑一致 c=('c', 'last') )
2. 在自定义函数中替换first()的写法
如果你一定要用apply,可以用以下方式替代x['b'].first():
- 直接取第一个元素(不跳过缺失值):
x['b'].iloc[0] - 和GroupBy.first()逻辑一致(跳过缺失值取第一个非NA):
x['b'].dropna().iloc[0] - 或者用
head(1):x['b'].head(1).iloc[0]
修改后的自定义函数:
def f(x): d = {} d['a'] = x['a'].max() d['b'] = x['b'].dropna().iloc[0] # 替换first() d['c'] = x['c'].last() return pd.Series(d, index=['a', 'b', 'c']) require_data = required_data.groupby(['S','id', 'lane', 'timestamp','E']).apply(f)
补充说明
关于x['c'].last():这里的Series.last()同样是时间序列方法,但如果你的c列不是时间索引的话,它其实会返回最后一个元素(和iloc[-1]效果一样),不过为了避免混淆,也可以改成x['c'].iloc[-1],逻辑更清晰。
内容的提问来源于stack exchange,提问作者HH____HH
相关产品推荐
相关产品推荐

