Pandas按ROU_ROUTE_ID分组聚合点列表的实现难题
解决方案
方法一:修复自定义函数的分组聚合
你之前的问题是没在自定义函数里正确访问分组后的列,其实分组后的x是一个子DataFrame,直接通过列名就能读取数据。可以这么实现:
import pandas as pd # 加载示例数据 data = pd.DataFrame([ [502, 'S', 'A1', 1, 'BRY', 'LUREN'], [502, 'S', 'A1', 2, 'LUREN', 'DJL'], [502, 'S', 'A1', 3, 'DJL', 'LISMO'], [502, 'S', 'A1', 4, 'LISMO', 'SIROD'], [502, 'S', 'A100', 1, 'KL', '*ROS1'], [502, 'S', 'A100', 2, '*ROS1', 'AMEPU'], [502, 'S', 'A100', 3, 'AMEPU', 'SARZI'] ], columns=['AC_ID','AC_PERIOD','ROU_ROUTE_ID','SEQUENCE_NR','SEG_POINT_FROM_ID','SEG_POINT_TO_ID']) def get_route_points(df): # 提取所有起点 from_points = df['SEG_POINT_FROM_ID'].tolist() # 提取分组最后一个终点 last_to_point = df['SEG_POINT_TO_ID'].iloc[-1] # 合并成完整点列表 return from_points + [last_to_point] # 分组执行聚合 result = data.groupby('ROU_ROUTE_ID').apply(get_route_points) # 输出你要的格式 for route_id, points in result.items(): print(f"{route_id},{points}")
运行后输出:
A1,['BRY', 'LUREN', 'DJL', 'LISMO', 'SIROD'] A100,['KL', '*ROS1', 'AMEPU', 'SARZI']
方法二:更高效的Pandas原生聚合(避免apply)
如果数据集规模较大,apply的性能会受限,推荐用agg分别聚合不同列再合并,利用Pandas向量化操作提速:
# 分别聚合:起点列转列表,终点列取最后一个值 agg_data = data.groupby('ROU_ROUTE_ID').agg( from_points=('SEG_POINT_FROM_ID', list), last_to=('SEG_POINT_TO_ID', lambda x: x.iloc[-1]) ) # 合并两列得到完整点列表 agg_data['full_points'] = agg_data.apply(lambda row: row['from_points'] + [row['last_to']], axis=1) # 输出目标格式 for route_id, row in agg_data.iterrows(): print(f"{route_id},{row['full_points']}")
关于你之前的代码问题
你写的data.groupby('ROU_ROUTE_ID')[['SEG_POINT_FROM_ID','SEG_POINT_TO_ID']].apply(lambda x: f(x))本身逻辑没问题,只要f(x)内部正确用x['SEG_POINT_FROM_ID']和x['SEG_POINT_TO_ID']访问列即可,之前应该是函数内部的写法有误。
内容的提问来源于stack exchange,提问作者Filip
相关产品推荐
相关产品推荐

