Python3.7 & Pandas:利用行中列值作为查找键生成目标新列的高效实现求助(避免逐行迭代)
高效实现Pandas DataFrame的标签匹配填充
嘿,这个需求用Pandas的矢量化操作就能完美解决,绝对比逐行迭代快N倍,完全适配你25000行的数据集规模!下面给你一步步拆解方案:
第一步:构建前缀到MID_LEVEL标签的映射字典
首先我们需要把所有LABEL_PATH的前9位前缀,和对应的MID_LEVEL标签对应起来。假设你的DataFrame里已经包含了MID_LEVEL类型的行(就是那些LABEL为MID_LEVEL1、MID_LEVEL2这类的行),我们可以直接从这些行里提取映射关系:
# 筛选出MID_LEVEL类型的行,提取前9位路径作为键,LABEL作为值构建字典 mid_level_map = df[df['LABEL'].str.contains('MID_LEVEL')].assign( path_prefix=lambda x: x['LABEL_PATH'].str.slice(0, 9) ).set_index('path_prefix')['LABEL'].to_dict()
这里用str.slice(0,9)精准截取前9位字符,assign临时生成前缀列,最后转成字典。如果存在重复前缀的情况,可以提前用drop_duplicates处理,避免后面的条目覆盖前面的。
第二步:矢量化填充目标列
接下来我们用Pandas的loc或者np.where给标记为LOW的行填充目标列,全程都是矢量化操作,没有低效的循环:
方法一:用loc定向赋值
# 初始化目标列 df['DESIRED_OUTPUT'] = None # 仅对LABEL为LOW的行,用前缀匹配映射字典填充 low_mask = df['LABEL'] == 'LOW' df.loc[low_mask, 'DESIRED_OUTPUT'] = df.loc[low_mask, 'LABEL_PATH'].str.slice(0,9).map(mid_level_map)
方法二:用np.where一行搞定
如果你喜欢更简洁的写法,np.where也能实现同样的效果:
import numpy as np df['DESIRED_OUTPUT'] = np.where( df['LABEL'] == 'LOW', df['LABEL_PATH'].str.slice(0,9).map(mid_level_map), None # 非LOW行可以设为None、空字符串或者其他默认值,按需调整 )
额外处理:匹配不到的情况
如果有些LOW行的前缀在映射字典里找不到,map会返回NaN,你可以用fillna给这些值设置默认值,比如:
df['DESIRED_OUTPUT'] = np.where( df['LABEL'] == 'LOW', df['LABEL_PATH'].str.slice(0,9).map(mid_level_map).fillna('NO_MATCH'), None )
为什么这个方案高效?因为Pandas的字符串操作(str.slice)、map和loc都是底层用C实现的矢量化操作,完全避开了Python层面的逐行循环,处理25000行数据基本是毫秒级的速度,比用apply或者for循环快几十甚至上百倍。
内容的提问来源于stack exchange,提问作者J. Roybomb
相关产品推荐
相关产品推荐

