Pandas DataFrame按条件创建分类列:新列全为NA,如何解决?
车辆分类列赋值问题排查与解决
场景描述
现有Pandas DataFrame包含「Vehicle Class」列,需根据自定义分类规则新增「Vehicle Type」列,分类规则如下:
Two_W_Personal = ['MOPED', 'M-CYCLE/SCOOTER', 'M-CYCLE/SCOOTER-WITH SIDE CAR', 'MOTORISED CYCLE (CC > 25CC)'] Two_W_Shared = ['MOTOR CYCLE/SCOOTER-USED FOR HIRE'] Three_W_Personal = ['THREE WHEELER (PERSONAL)'] Three_W_Shared = ['THREE WHEELER (PASSENGER)'] Three_W_Shared_LowSpeed = ['E-RICKSHAW(P)'] Three_W_Goods = ['THREE WHEELER (GOODS)'] Three_W_Goods_LowSpeed = ['E-RICKSHAW WITH CART (G)'] Four_W_Personal = ['MOTOR CAR'] Four_W_Shared = ['MOTOR CAB', 'LUXURY CAB', 'LUXURY CAB'] Bus = ['BUS', 'OMNI BUS', 'OMNI BUS (PRIVATE USE)'] Institution_Bus = ['EDUCATIONAL INSTITUTION BUS']
尝试用以下循环代码赋值,但运行后「Vehicle Type」列全部填充为NA:
for vehicle in master_df['Vehicle Class']: if vehicle in Two_W_Personal: master_df['Vehicle Type'] = '2W_Personal' elif vehicle in Two_W_Shared: master_df['Vehicle Type'] = '2W_Shared' elif vehicle in Three_W_Personal: master_df['Vehicle Type'] = '3W_Personal' elif vehicle in Three_W_Shared: master_df['Vehicle Type'] = '3W_Shared' elif vehicle in Three_W_Shared_LowSpeed: master_df['Vehicle Type'] = '3W_Shared_LowSpeed' elif vehicle in Three_W_Goods: master_df['Vehicle Type'] = '3W_Goods' elif vehicle in Three_W_Goods_LowSpeed: master_df['Vehicle Type'] = '3W_Goods_LowSpeed' elif vehicle in Four_W_Personal: master_df['Vehicle Type'] = '4W_Personal' elif vehicle in Four_W_Shared: master_df['Vehicle Type'] = '4W_Shared' elif vehicle in Bus: master_df['Vehicle Type'] = 'Bus' elif vehicle in Institution_Bus: master_df['Vehicle Type'] = 'Institution Bus' else: master_df['Vehicle Type'] = 'NA'
错误原因
循环逻辑存在核心问题:每次判断后直接给整个「Vehicle Type」列赋值,而非对应行。遍历到最后一个vehicle时,若该值不在任何分类列表中,就会将整列覆盖为NA,导致之前所有赋值结果失效。此外,逐行遍历DataFrame是低效操作,不符合Pandas的向量式设计理念。
解决方法
方法1:修复循环逻辑(不推荐,仅作原理演示)
通过索引定位到具体行赋值,避免覆盖整列:
# 先初始化新列为默认值'NA' master_df['Vehicle Type'] = 'NA' # 遍历索引与对应值 for idx, vehicle in enumerate(master_df['Vehicle Class']): if vehicle in Two_W_Personal: master_df.loc[idx, 'Vehicle Type'] = '2W_Personal' elif vehicle in Two_W_Shared: master_df.loc[idx, 'Vehicle Type'] = '2W_Shared' elif vehicle in Three_W_Personal: master_df.loc[idx, 'Vehicle Type'] = '3W_Personal' elif vehicle in Three_W_Shared: master_df.loc[idx, 'Vehicle Type'] = '3W_Shared' elif vehicle in Three_W_Shared_LowSpeed: master_df.loc[idx, 'Vehicle Type'] = '3W_Shared_LowSpeed' elif vehicle in Three_W_Goods: master_df.loc[idx, 'Vehicle Type'] = '3W_Goods' elif vehicle in Three_W_Goods_LowSpeed: master_df.loc[idx, 'Vehicle Type'] = '3W_Goods_LowSpeed' elif vehicle in Four_W_Personal: master_df.loc[idx, 'Vehicle Type'] = '4W_Personal' elif vehicle in Four_W_Shared: master_df.loc[idx, 'Vehicle Type'] = '4W_Shared' elif vehicle in Bus: master_df.loc[idx, 'Vehicle Type'] = 'Bus' elif vehicle in Institution_Bus: master_df.loc[idx, 'Vehicle Type'] = 'Institution Bus'
方法2:Pandas向量式映射(推荐,高效简洁)
构建分类映射字典,用map方法一次性完成赋值:
# 构建映射字典 vehicle_map = {} # 批量添加各类别映射 vehicle_map.update({v: '2W_Personal' for v in Two_W_Personal}) vehicle_map.update({v: '2W_Shared' for v in Two_W_Shared}) vehicle_map.update({v: '3W_Personal' for v in Three_W_Personal}) vehicle_map.update({v: '3W_Shared' for v in Three_W_Shared}) vehicle_map.update({v: '3W_Shared_LowSpeed' for v in Three_W_Shared_LowSpeed}) vehicle_map.update({v: '3W_Goods' for v in Three_W_Goods}) vehicle_map.update({v: '3W_Goods_LowSpeed' for v in Three_W_Goods_LowSpeed}) vehicle_map.update({v: '4W_Personal' for v in Four_W_Personal}) vehicle_map.update({v: '4W_Shared' for v in Four_W_Shared}) vehicle_map.update({v: 'Bus' for v in Bus}) vehicle_map.update({v: 'Institution Bus' for v in Institution_Bus}) # 生成新列,未匹配项填充为'NA' master_df['Vehicle Type'] = master_df['Vehicle Class'].map(vehicle_map).fillna('NA')
方法3:使用replace方法实现
replace同样支持字典批量替换,效果与map一致:
master_df['Vehicle Type'] = master_df['Vehicle Class'].replace(vehicle_map).fillna('NA')
内容的提问来源于stack exchange,提问作者Ankit Bhatt
相关产品推荐
相关产品推荐

