生成行程全排列DataFrame时Kayak搜索URL生成异常排查
问题分析与修复方案
问题根源
生成kayak_search_url的代码中,所有航段的起点都固定取了出发城市的IATA码(iata[x['origin']]),没有按照行程逻辑用上一航段的终点作为下一航段的起点,导致后续航段起点始终为AMS,不符合预期。
修复后的完整代码
import itertools import pandas as pd # 定义行程基础参数 start_city = 'Amsterdam' end_city = 'Amsterdam' start_date = '2023-02-14' cities = ['Warsaw', 'Bogota', 'Milan', 'Santo Domingo'] days = [3,3,3,2] def generate_permutations(cities, days, start_city, end_city, start_date): city_to_days = dict(zip(cities, days)) permutations = list(itertools.permutations(cities)) df = pd.DataFrame(permutations, columns=['city' + str(i) for i in range(1, len(cities) + 1)]) df['origin'] = start_city df['end'] = end_city first_column = df.pop('origin') df.insert(0, 'origin', first_column) st_dt = pd.to_datetime(start_date) df = df.assign(flight_dt_1=st_dt) for i in range(len(cities)): df['flight_dt_' + str(i + 2)] = df['flight_dt_' + str(i + 1)] + df['city' + str(i + 1)].map(city_to_days).map(lambda x: pd.Timedelta(days=x)) # IATA城市编码映射 iata = {'Amsterdam': 'AMS', 'Warsaw': 'WAW', 'Bogota': 'BOG', 'Milan': 'MIL', 'Santo Domingo': 'SDQ'} url = 'https://www.kayak.com/flights/' # 修改URL生成逻辑,按行程串联航段 df['kayak_search_url'] = df.apply(lambda x: url + ''.join( # 构建完整行程序列:起点 → 各停留城市 → 终点,配对相邻城市与对应日期 [f"{iata[prev_city]}-{iata[current_city]},nearby/{date.strftime('%Y-%m-%d')}/" for prev_city, current_city, date in zip( [x['origin']] + [x[f'city{i+1}'] for i in range(len(cities))], [x[f'city{i+1}'] for i in range(len(cities))] + [x['end']], [x[f'flight_dt_{i+1}'] for i in range(len(cities)+1)] )] ) + '?sort=bestflight_a', axis=1) return df # 测试调用示例 result_df = generate_permutations(cities, days, start_city, end_city, start_date) print(result_df['kayak_search_url'].iloc[0])
关键修改说明
- 构建完整行程序列:将起点城市、排列后的各停留城市、终点城市串联成连续列表,确保行程逻辑连贯
- 配对相邻城市与日期:通过
zip同时获取上一城市(航段起点)、当前城市(航段终点)及对应出发日期 - 动态生成航段URL:每个航段的起点自动继承上一航段的终点,彻底解决固定起点的问题
内容的提问来源于stack exchange,提问作者June Smith
相关产品推荐
相关产品推荐

