为何Pandas中apply比矢量化更快?我的矢量化用法有误吗?
问题分析
你的矢量化写法确实存在效率损耗问题——多次链式调用str访问器会产生大量中间Series,累积的函数调用和内存开销抵消了矢量化的优势。
原代码里,你先调用str.strip()生成新Series并赋值回原列,接着又两次调用str访问器(str[0].str.upper()和str[1:])。每一次str操作都需要Pandas内部做类型检查、创建新的StringArray对象,这些额外开销叠加后,反而不如apply一次性处理每个元素高效。
优化后的矢量化写法
把多个字符串操作合并为更少步骤,减少中间变量生成:
import pandas as pd import time # 生成数据 data = [' example text '] * 1000000 df = pd.DataFrame(data, columns=['tr_content']) # 优化后的矢量化方法 start_time = time.time() stripped = df['tr_content'].str.strip() df['tr_content'] = stripped.str[0].str.upper() + stripped.str[1:] print("优化后矢量化执行时间: ", time.time() - start_time) # 重新生成数据 df = pd.DataFrame(data, columns=['tr_content']) # apply方法 start_time = time.time() capitalize_at_first = lambda x: (y := str(x).strip()) and y[0].upper() + y[1:] df['tr_content'] = df['tr_content'].apply(capitalize_at_first) print("apply执行时间: ", time.time() - start_time)
也可以用正则替换进一步合并步骤:
start_time = time.time() df['tr_content'] = df['tr_content'].str.strip().str.replace(r'^.', lambda m: m.group().upper(), regex=True) print("正则矢量化执行时间: ", time.time() - start_time)
优化后更快的原因
- 减少
str访问器调用次数:原代码调用3次str(strip、[0].upper、[1:]),优化后只调用2次,正则版本更是合并为2次链式调用。 - 避免重复strip操作:原代码第二次赋值时,
df['tr_content'].str[1:]基于已strip的列,但提前将strip结果存为中间变量,就不用重复执行strip逻辑。
额外提示
Pandas的str.capitalize()方法会将首字母大写、其余字母转为小写,不符合你保留原字符串后续字符的需求,所以不能直接用。如果场景允许后续字符转小写,str.strip().str.capitalize()会是更简洁高效的选择。
内容的提问来源于stack exchange,提问作者HERIUN
相关产品推荐
相关产品推荐

