Pandas:为多输入场景下的apply方法添加额外参数
处理Pandas两列数据:apply带参数 vs iterrows,且不覆盖已有值
嘿,我来帮你梳理下这个问题~你想要用Pandas处理两列数据,用apply带额外参数做正则匹配,还不能覆盖目标列的已有值,同时纠结要不要用iterrows对吧?咱们一步步来拆解:
核心结论:优先用apply(或向量化方法),别用iterrows
iterrows是逐行迭代,性能极差,尤其是数据量大的时候,完全不推荐。apply虽然也是逐行处理,但比iterrows高效不少;如果逻辑简单,用向量化的字符串方法性能最优。
方法1:用apply处理两列+传递额外参数
首先定义一个自定义函数,接收行数据和额外的正则参数,判断目标列b是否为空,为空就执行匹配,否则保留原值:
import re import pandas as pd import numpy as np # 生成测试数据 df = pd.DataFrame({ 'a': np.random.choice(['the_panda','it_python','my_shark'], 6), }) df["b"] = "" # 给其中一行b设置已有值,测试不覆盖逻辑 df.loc[2, 'b'] = 'existing_value' def update_b(row, regex_pattern): # 如果b列已有内容,直接返回原值 if row['b']: return row['b'] # 匹配a列的正则内容 match_result = re.search(regex_pattern, row['a']) return match_result.group(1) if match_result else row['b'] # 定义正则模式作为额外参数 target_pattern = r'_(.*)' # 用apply逐行处理,axis=1表示按行操作,args传递额外参数 df['b'] = df.apply(update_b, axis=1, args=(target_pattern,))
执行后你会看到,第2行的b列依然是existing_value,其他空的b列被填充了从a列匹配到的后缀(比如panda、python)。
方法2:更高效的向量化实现(推荐)
如果只是简单的正则提取+不覆盖已有值,完全不用写自定义函数,用Pandas的向量化字符串方法str.extract结合loc就能搞定,性能比apply还要好:
target_pattern = r'_(.*)' # 只更新b列为空的行,用str.extract提取a列的匹配内容 df.loc[df['b'] == '', 'b'] = df.loc[df['b'] == '', 'a'].str.extract(target_pattern, expand=False)
这种方法是批量操作,避免了逐行处理,大数据集下速度会快很多。
为什么别用iterrows?
虽然iterrows也能实现需求,但它是逐行遍历数据,每一行都要做一次操作,而且返回的是行的副本,修改时还要用df.loc才能生效,代码繁琐且性能拉胯。比如下面是用iterrows的实现,对比下就能看出差距:
target_pattern = r'_(.*)' for idx, row in df.iterrows(): if not row['b']: match = re.search(target_pattern, row['a']) if match: df.loc[idx, 'b'] = match.group(1)
如果你的数据集有几万行甚至更多,iterrows会慢到让人崩溃,完全没必要用它。
内容的提问来源于stack exchange,提问作者sparrow
相关产品推荐
相关产品推荐

