如何统计datetime64[ns]列分组唯一日期数并解决Series调用报错
问题描述
- 现有Pandas DataFrame
df,包含id、timeframe、type三个字段:timeframe列数据类型为datetime64[ns]type列取值仅为'A'或'B'
- 需求:筛选
df['type'] == 'A'的记录,统计每个id对应的唯一日期总数量 - 原实现代码运行报错
TypeError: 'Series' object is not callable,原代码如下:
df = df.groupby(['id', 'type']).timeframe.apply(lambda x: x.dt.date()).unique().rename('test').reset_index()
错误原因
- 直接触发报错的点:
x.dt.date是datetime64类型列的属性,返回提取日期后的Series对象,不是可调用的方法,后续加()相当于把Series当函数执行,直接抛出'Series' object is not callable错误。 - 代码逻辑存在额外问题:
- 未提前筛选
type == 'A'的记录,会将类型为B的数据纳入统计 unique()写在apply()外层,作用是对全量聚合结果做去重,而非对每个分组内的日期去重计数,不符合需求- 用
apply实现分组去重计数效率低,pandas原生提供了nunique()方法直接实现该逻辑。
- 未提前筛选
正确实现代码
优先使用性能更好的原生分组聚合写法,逻辑清晰:
# 筛选type为A的记录,按id分组统计唯一日期数 result = ( df[df["type"] == "A"] # 提取日期部分,注意dt.date是属性,不要加括号 .assign(stat_date=lambda x: x["timeframe"].dt.date) .groupby("id") ["stat_date"] .nunique() # 直接统计分组内唯一值个数 .rename("unique_date_cnt") .reset_index() )
如果需要保留type字段到结果中,只需要把type加入分组键即可,因为提前做了筛选,结果中type值全为'A':
result = ( df[df["type"] == "A"] .assign(stat_date=lambda x: x["timeframe"].dt.date) .groupby(["id", "type"]) ["stat_date"] .nunique() .rename("unique_date_cnt") .reset_index() )
如果坚持用apply写法(不推荐,性能弱于原生nunique),修正后代码如下:
result = ( df[df["type"] == "A"] .groupby("id") .timeframe .apply(lambda x: x.dt.date.unique().size) .rename("unique_date_cnt") .reset_index() )
内容的提问来源于stack exchange,提问作者coderuk
相关产品推荐
相关产品推荐

