Pandas条件子集筛选优化:基于.loc[]提升性能及代码改进问询
优化方案:DataFrame字典列表列的筛选与长度计算
一、快速计算字典列表长度(优化length_associated_PP列)
放弃逐行循环,直接用Pandas的矢量化方法处理,性能比循环提升数倍:
# 基础版:直接用str.len()处理列表列 df['length_associated_PP'] = df['PP_associated'].str.len() # 健壮版:处理空值/非列表情况,填充0并转为整数 df['length_associated_PP'] = df['PP_associated'].str.len().fillna(0).astype(int)
如果列中存在None或非列表类型值,也可以用apply做兜底判断:
df['length_associated_PP'] = df['PP_associated'].apply(lambda x: len(x) if isinstance(x, list) else 0)
二、基于字典列表中country值的行筛选优化
方法1:矢量化判断配合.loc[]筛选
用apply生成布尔掩码,再通过.loc[]提取符合条件的行,比逐行遍历高效得多:
# 示例:筛选包含country为"China"的行 target_country = "China" mask = df['PP_associated'].apply( lambda lst: any(d.get('country') == target_country for d in lst) if isinstance(lst, list) else False ) filtered_df = df.loc[mask].copy() # 多国家筛选版 target_countries = {"China", "US", "Japan"} mask = df['PP_associated'].apply( lambda lst: any(d.get('country') in target_countries for d in lst) if isinstance(lst, list) else False ) filtered_df = df.loc[mask].copy()
方法2:展开列表为多行(高扩展性方案)
如果后续需要对字典内的其他字段做分析,推荐用explode把列表拆成单独行,筛选后再关联回原DataFrame,这种方式更适配生产环境的复杂需求:
# 展开字典列表为单独行,保留原行索引 exploded_df = df.explode('PP_associated').reset_index(names='original_index') # 提取字典中的country字段 exploded_df['country'] = exploded_df['PP_associated'].apply(lambda d: d.get('country')) # 筛选目标国家,获取原行的唯一索引 valid_indices = exploded_df[exploded_df['country'].isin(target_countries)]['original_index'].unique() # 用.loc[]提取原DataFrame中符合条件的行 filtered_df = df.loc[valid_indices].copy()
三、生产环境扩展性建议
- 配置化:把目标国家、列名等参数抽离成配置项(比如函数参数、配置文件),避免硬编码
- 异常校验:提前对
PP_associated列做类型校验,处理空值、非列表等异常情况,防止运行时崩溃 - 大数据量优化:如果数据量达到百万级以上,可尝试用
swifter库让apply自动切换到Numba/Dask加速,或者将字典列表转为嵌套DataFrame处理:
# 把字典列表转为结构化的嵌套DataFrame pp_structured = pd.json_normalize(df['PP_associated']) # 后续可直接基于该DataFrame做复杂筛选,再与原表关联
内容的提问来源于stack exchange,提问作者Hugoz13
相关产品推荐
相关产品推荐

