如何高效遍历DataFrame行,提取匹配角色列的属性ID?
高效提取匹配角色列的数字数据方案
方法1:使用apply配合自定义函数(简洁易读)
相比iterrows逐行遍历的低效,apply内部做了性能优化,能大幅提升处理速度,同时代码逻辑清晰:
import ast import pandas as pd def get_cleaned_prop_ids(row): role = row['primary_role'] role_data_str = row[role] # 处理空值避免报错 if pd.isna(role_data_str): return [] # 转换字符串字典为实际对象,提取organization列表 role_dict = ast.literal_eval(role_data_str) org_list = role_dict.get('organization', []) # 清洗数字并转为整数 return [int(item.strip()) for item in org_list if item.strip().isdigit()] # 按行批量处理,生成新列 users_df['prop_id'] = users_df.apply(get_cleaned_prop_ids, axis=1)
方法2:矢量化+列表推导式(性能更优)
利用df.lookup一次性提取所有行对应角色列的数据,再通过列表推导式批量处理,完全规避逐行操作的开销:
import ast import pandas as pd # 1. 一次性提取每行对应角色列的字符串数据 role_column_values = users_df.lookup(users_df.index, users_df['primary_role']) # 2. 批量转换字符串字典为字典对象(处理空值) role_dicts = [] for val in role_column_values: if pd.notna(val): role_dicts.append(ast.literal_eval(val)) else: role_dicts.append({}) # 3. 提取organization列表并清洗数字 prop_id_list = [] for d in role_dicts: org_list = d.get('organization', []) cleaned = [int(item.strip()) for item in org_list if item.strip().isdigit()] prop_id_list.append(cleaned) # 4. 赋值给新列 users_df['prop_id'] = prop_id_list
额外优化:提前批量转换角色列的字符串字典
如果角色列数量不多,可以先一次性把所有角色列的字符串字典转成实际字典,后续处理会更高效:
# 筛选出所有角色列(排除primary_role) role_columns = [col for col in users_df.columns if col != 'primary_role'] # 批量转换字符串为字典 users_df[role_columns] = users_df[role_columns].applymap( lambda x: ast.literal_eval(x) if pd.notna(x) else {} ) # 简化版处理函数 def get_cleaned_prop_ids(row): role_dict = row[row['primary_role']] org_list = role_dict.get('organization', []) return [int(item.strip()) for item in org_list if item.strip().isdigit()] users_df['prop_id'] = users_df.apply(get_cleaned_prop_ids, axis=1)
性能说明
iterrows会把每一行转为Series对象,带来大量额外开销;上述方法要么利用pandas矢量化操作,要么用原生列表推导式,处理5000+行数据的速度能提升数倍。
内容的提问来源于stack exchange,提问作者jp207
相关产品推荐
相关产品推荐

