You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何加速DataFrame中自定义函数的apply运算?

加速Pandas百万行DataFrame列计算的方案

针对你用df["col"].apply(my_obj.move, args=(1,))处理百万行数据速度极慢的问题,以下是几个实用的加速方案:

1. 优先用向量化运算替代逐元素apply

apply本质是逐元素调用Python函数,百万级数据会产生巨大的函数调用开销。如果my_obj.move的逻辑是纯数值运算,直接改用Pandas/Numpy的向量化操作,速度能提升几十到上百倍。

操作步骤:

  • 把move方法的逻辑改造成支持数组输入的形式(直接基于Numpy数组运算)
  • 直接对整列数据进行运算

示例:
假设原来的move方法是:

class MyClass:
    def move(self, x, c):
        # 示例运算:x乘以2加常量c
        return x * 2 + c

改造后,新增一个支持向量化的方法:

class MyClass:
    def move(self, x, c):
        return x * 2 + c
    
    def move_vectorized(self, arr, c):
        # 直接对Numpy数组进行运算,无需循环
        return arr * 2 + c

然后替换原代码:

# 先把列转成Numpy数组(可选,Pandas Series本身支持向量化)
col_arr = df["col"].to_numpy()
df["new_col"] = my_obj.move_vectorized(col_arr, 1)

如果逻辑简单,甚至可以直接写一行:

df["new_col"] = df["col"] * 2 + 1  # 等价于上面的move逻辑

2. 用Numba编译加速数值运算

如果move的逻辑复杂,无法直接用简单向量化实现,可以用Numba将函数编译为机器码,消除Python循环开销。

操作步骤:

  • 把move的逻辑提取为纯Python函数(Numba对类方法支持有限,优先用纯函数)
  • 用numba.jit装饰器编译函数
  • 直接对Numpy数组调用编译后的函数

示例:

from numba import jit

# 提取move的逻辑为纯函数,用numba编译
@jit(nopython=True)  # nopython模式下速度最快
def move_numba(x, c):
    # 这里写原move方法的数值运算逻辑,比如复杂的条件判断或循环
    if x > 100:
        return x * 1.5 + c
    else:
        return x * 0.8 + c

# 对整列的Numpy数组调用编译后的函数
df["new_col"] = move_numba(df["col"].to_numpy(), 1)

3. 并行处理(适合无法向量化的复杂逻辑)

如果上述两种方法都无法适配你的move逻辑,可以用并行apply来分摊计算时间。推荐用swifter库(自动选择最优执行方式),或者手动用多进程。

用swifter的示例:

import swifter

# swifter会自动判断是用向量化还是并行apply,无需手动调整
df["new_col"] = df["col"].swifter.apply(my_obj.move, args=(1,))

手动多进程示例(无需额外库):

from multiprocessing import Pool
import numpy as np

# 把数据拆分成多个块
num_chunks = 4  # 根据CPU核心数调整
col_chunks = np.array_split(df["col"].to_numpy(), num_chunks)

# 定义并行处理的函数
def process_chunk(chunk):
    return [my_obj.move(x, 1) for x in chunk]

# 启动进程池处理
with Pool(num_chunks) as pool:
    results = pool.map(process_chunk, col_chunks)

# 合并结果并赋值
df["new_col"] = np.concatenate(results)

为什么原代码慢?

apply是逐元素调用Python函数,每个元素的处理都要经历Python函数调用的开销(比如参数传递、栈帧创建等)。百万级数据下,这些微小的开销会被无限放大,导致运行时间急剧增加。而向量化/Numba/并行处理都是从消除或分摊这部分开销入手,从而大幅提升速度。

内容的提问来源于stack exchange,提问作者roulette01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 14:05:14