基于条件使用Python Pandas编辑快递调度文件的条目顺序与内容
解决快递调度行程拆分的Pandas实现方案
你的需求核心是根据courier_status标记,将特定行程拆分为「原起点→快递起点→快递终点→原终点」的三段行程,同时重新生成每个用户的行程ID。这个场景用分组遍历的方式最直观可靠,也能适配你实际的多列大数据量情况,我给你一步步拆解实现:
核心思路
- 按
id分组:每个用户的行程是独立序列,分组后处理不会互相干扰 - 遍历每组内的原始行程:
- 普通行程(
courier_status=False)直接保留,标记status='normal' - 需要绕行的行程(
courier_status=True)拆分为3段:- 原起点→快递起点(
status='courier') - 快递起点→快递终点(
status='courier') - 快递终点→原终点(
status='normal')
- 原起点→快递起点(
- 普通行程(
- 为每个用户的新行程重新生成连续的
trip_id - 合并所有分组结果得到最终调度表
完整代码实现
import pandas as pd # 模拟你的原始数据(实际使用时替换成读取你的文件,比如pd.read_csv/Excel) raw_data = { 'id': [1,1,2,2,2], 'trip_id': [1,2,1,2,3], 'origin': ['A','B','F','G','H'], 'destination': ['B','C','G','H','I'], 'courier_status': [False, True, False, True, False], 'package_origin': [None, 'X', None, 'Q', None], 'package_destination': [None, 'Y', None, 'R', None] } df = pd.DataFrame(raw_data) # 定义处理单用户行程分组的函数 def process_user_trips(group): new_trip_list = [] # 遍历该用户的每一条原始行程 for _, row in group.iterrows(): if not row['courier_status']: # 普通行程直接添加 new_trip_list.append({ 'id': row['id'], 'origin': row['origin'], 'destination': row['destination'], 'status': 'normal' # 如果有其他列(比如时间、备注),直接在这里追加:'列名': row['列名'] }) else: # 拆分快递绕行行程 # 1. 原起点→快递起点 new_trip_list.append({ 'id': row['id'], 'origin': row['origin'], 'destination': row['package_origin'], 'status': 'courier' # 其他列按需复制,比如'departure_time': row['departure_time'] }) # 2. 快递起点→快递终点 new_trip_list.append({ 'id': row['id'], 'origin': row['package_origin'], 'destination': row['package_destination'], 'status': 'courier' # 其他列按需复制 }) # 3. 快递终点→原终点 new_trip_list.append({ 'id': row['id'], 'origin': row['package_destination'], 'destination': row['destination'], 'status': 'normal' # 其他列按需复制 }) # 转换为DataFrame并生成连续的trip_id new_trips_df = pd.DataFrame(new_trip_list) new_trips_df['trip_id'] = new_trips_df.groupby('id').cumcount() + 1 # 每个用户从1开始计数 # 调整列顺序和目标一致 new_trips_df = new_trips_df[['id', 'trip_id', 'origin', 'destination', 'status']] return new_trips_df # 应用分组处理并合并结果 newSchedule = df.groupby('id', group_keys=False).apply(process_user_trips).reset_index(drop=True) # 查看最终结果 print(newSchedule)
代码运行结果
id trip_id origin destination status 0 1 1 A B normal 1 1 2 B X courier 2 1 3 X Y courier 3 1 4 Y C normal 4 2 1 F G normal 5 2 2 G Q courier 6 2 3 Q R courier 7 2 4 R H normal 8 2 5 H I normal
针对你的疑问的补充说明
- 关于你的原始思路:你之前想“新增行程追加后去重”的问题在于,原有的
courier_status=True的行程是需要被替换掉的,而不是保留后追加,直接生成新行程列表的方式更准确,避免了去重逻辑的潜在错误。 - 循环vs np.where:
np.where适合生成单行的条件列,但这里需要根据一行生成多行,所以分组+循环的方式更直观可控,而且代码可读性高,后续维护扩展也方便。 - 通用性适配:如果你的实际数据有更多列(比如出发时间、快递类型等),只需要在
new_trip_list.append()的字典里添加对应的键值对即可,比如复制原行的列值,或者根据业务逻辑修改(比如快递行程的时间可以在原时间基础上调整)。
内容的提问来源于stack exchange,提问作者Ricky
相关产品推荐
相关产品推荐

