Pandas DataFrame按id聚合重复行:新增计数列并保留原有字段的实现方法
Pandas按ID聚合去重并统计出现次数的实现方案
你目前的实现存在两个可直接修复的问题:
- 直接对分组结果应用
agg(np.mean)时,字符串类型的status列会因为无法计算数值均值被自动丢弃 - 没有显式定义分组内的行数统计规则,无法生成
count列
推荐实现方法(逐列指定聚合规则,通用性最强)
这种方法不需要依赖“同ID的所有行字段完全一致”的前提,可以根据每列的业务逻辑自由指定聚合方式,适配场景最多:
- 按
id分组后,对需要保留原始值的列(status/lat/lon)指定取分组内的第一个值(你的示例中同ID的这些值完全一致,取第一值和取唯一值、均值的结果完全相同) - 对需要统计的
count列指定取分组内的行数,用size规则即可
这里加
as_index=False是为了避免分组键id变成DataFrame索引,保持输出表的列结构和原表一致。
import pandas as pd import numpy as np # 分组聚合实现 grouped = df.groupby('id', as_index=False).agg( status=('status', 'first'), lat=('lat', 'first'), lon=('lon', 'first'), count=('id', 'size') ) # 如需和示例输出完全对齐(仅重复ID填写count值,单出现ID的count留空) grouped.loc[grouped['count'] == 1, 'count'] = np.nan
最终输出的表结构和字段值和你给出的预期效果完全一致。
轻量化替代方案(适配同ID行完全重复的场景)
如果确认你的数据源里同一个ID对应的所有非ID字段完全没有差异,只是存在整行重复的情况,可以用执行效率更高的两步实现:
- 直接按
id去重,保留每个ID的第一行 - 统计每个ID的出现次数,按ID值合并到去重后的表上
# 按ID去重 dedup_df = df.drop_duplicates(subset=['id'], keep='first').reset_index(drop=True) # 统计每个ID的出现次数 id_count = df['id'].value_counts().rename('count').reset_index() # 合并结果 final_df = dedup_df.merge(id_count, on='id', how='left') # 对齐示例的留空规则 final_df.loc[final_df['count'] == 1, 'count'] = np.nan
注意:如果业务中存在同一个ID对应的status/lat/lon值不一致的情况,就不能直接用first或者去重的逻辑,需要根据实际需求替换为对应的聚合规则(比如取众数、取最近更新值、过滤异常值后取均值等)。
内容的提问来源于stack exchange,提问作者user971741
相关产品推荐
相关产品推荐

