如何在Pandas中按列分组并基于指定列首次出现条件去重
问题描述
我有一个行数较多、仅包含3列的DataFrame,示例数据如下:
import pandas as pd data = {'line_group': [1,1,8,8,4,4,5,5], 'route_order': [1,2,1,2,1,2,1,2], 'StartEnd':['20888->20850','20888->20850','20888->20850','20888->20850', '20961->20960','20961->20960','20961->20960','20961->20960']} df = pd.DataFrame(data)
我需要使用这份数据绘制点与点之间的路径,比如20888到20850的路径。但问题在于有大量trips/line_group都会经过这两个点,直接绘图会出现大量重叠且渲染速度极慢,不符合预期。
因此我需要筛选出每个唯一StartEnd对应的首个line_group的全部行数据,全量数据中的route_order不只有两段路径,可能包含更多节点(例如1,2,3,4,...)。我尝试过使用如下代码,但没有得到预期结果:
df.drop_duplicates(subset='StartEnd', keep="first")
原因是上述代码只会保留每个StartEnd的第一行记录,无法保留首个line_group对应的全部route_order行。
实现方案
方案1:transform匹配法
通过groupby的transform方法将每个StartEnd对应的首个line_group值广播到组内所有行,再做布尔筛选即可完整保留首个line_group的所有路径节点:
# 新增临时列存储每个StartEnd对应的首个line_group df['first_line_group'] = df.groupby('StartEnd')['line_group'].transform('first') # 筛选匹配的行,删除临时列 result = df[df['line_group'] == df['first_line_group']].drop(columns='first_line_group')
方案2:映射表merge法
先提取每个StartEnd对应的首个line_group映射表,再通过内连接匹配原表中符合条件的所有行,数据量较大时性能更优:
# 提取每个StartEnd的首个line_group映射 first_groups = df.drop_duplicates('StartEnd', keep='first')[['StartEnd', 'line_group']] # 内连接匹配所有符合条件的行 result = df.merge(first_groups, on=['StartEnd', 'line_group'], how='inner')
两种方案运行后得到的结果一致,如下所示:
| line_group | route_order | StartEnd |
|---|---|---|
| 1 | 1 | 20888->20850 |
| 1 | 2 | 20888->20850 |
| 4 | 1 | 20961->20960 |
| 4 | 2 | 20961->20960 |
内容的提问来源于stack exchange,提问作者glockm15
相关产品推荐
相关产品推荐

