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

如何加速超大型Pandas表的列计算并快速获取结果尾值?

高效向量化处理大规模表格计算方案

给定条件

  • Table1:固定数据表,行数可超过2亿行
  • Table1示例代码:
import pandas as pd

data = [
    [10.0, 10.0, 0.5, 1.0, 7.0, 1.1, 1.0],
    [10.0, 10.0, 0.5, 1.0, 8.0, 1.1, 1.0],
    [10.0, 20.0, 0.5, 1.0, 7.0, 1.1, 1.0],
    [10.0, 20.0, 0.5, 1.0, 8.0, 1.1, 1.0],
]

table1 = pd.DataFrame(
    data=data,
    columns=["a", "b", "c", "d", "e", "f", "g"]
)
  • Table1示例输出:
a     b    c    d    e    f    g
0  10.0  10.0  0.5  1.0  7.0  1.1  1.0
1  10.0  10.0  0.5  1.0  8.0  1.1  1.0
2  10.0  20.0  0.5  1.0  7.0  1.1  1.0
3  10.0  20.0  0.5  1.0  8.0  1.1  1.0

计算逻辑说明

calculate_table() 函数基于Table1每行的参数生成计算表,并返回计算表最后一行的关键值(如p[-1]、x[-1]等),示例代码如下:

import pandas as pd
import numpy as np

def calculate_table(
    a: float,
    b: float,
    c: float,
    d: float,
    e: int,
    f: float,
    g: float,
    pr: float = 10000,
):

    m = np.arange(e + 1)
    so = np.arange(e)

    # 核心计算逻辑
    p = d * (f ** m - 1) / (f - 1)
    s = pr * (1 - ((d * (f ** m - 1) / (f - 1)) / 100))
    q = np.r_[a, b * g ** so]
    r = np.cumsum(q)
    t = q / s
    u = np.cumsum(t)
    v = r / u
    w = v * (1 + (c / 100))
    x = ((w - s) / s) * 100
    y = a * (c / 100)
    z = r * (c / 100)

    data = {
        "m": m,
        "p": p,
        "s": s,
        "x": x,
        "w": w,
        "v": v,
        "q": q,
        "r": r,
        "t": t,
        "u": u,
        "y": y,
        "z": z,
    }

    table = pd.DataFrame(data=data)

    return p[-1], x[-1], y, z[-1]
  • 单条数据的计算表示例输出:
(   m          p            s         x             w             v    q     r         t         u     y      z
0  0   0.000000  10000.00000  0.500000  10050.000000  10000.000000   10    10  0.001000  0.001000  0.05  0.050
1  1   0.500000   9950.00000  0.701403  10019.789579   9969.939880   15    25  0.001508  0.002508  0.05  0.125
2  2   1.250000   9875.00000  0.936901   9967.519012   9917.929365   30    55  0.003038  0.005546  0.05  0.275
3  3   2.375000   9762.50000  1.258945   9885.404507   9836.223390   60   115  0.006146  0.011691  0.05  0.575
4  4   4.062500   9593.75000  1.727164   9759.449799   9710.895322  120   235  0.012508  0.024200  0.05  1.175
5  5   6.593750   9340.62500  2.432283   9567.815435   9520.214364  240   475  0.025694  0.049894  0.05  2.375
6  6  10.390625   8960.93750  3.524930   9276.804262   9230.651007  480   955  0.053566  0.103460  0.05  4.775
7  7  16.085938   8391.40625  5.273190   8833.901006   8789.951250  960  1915  0.114403  0.217862  0.05  9.575, 16.0859375, 5.273189534595566, 0.05, 9.575)

当前问题与需求

当前通过apply函数逐行处理40万行数据耗时约20分钟,效率极低。需要将计算逻辑改为全向量化操作,直接在Table1上批量计算每行对应的最终结果,新增为Table1的列。


向量化解决方案

核心思路

利用numpy的广播机制,为每行数据生成对应长度的序列,批量完成累积求和等操作,最后提取每行的最后一个结果值。

实现代码

import numpy as np
import pandas as pd

def vectorized_calculate(table1, pr=10000):
    # 提取列数据转为numpy数组
    a = table1['a'].values
    b = table1['b'].values
    c = table1['c'].values
    d = table1['d'].values
    e = table1['e'].values.astype(int)
    f = table1['f'].values
    g = table1['g'].values

    # 确定最大的e值,生成统一长度的m序列(不足的行后续用mask处理)
    max_e = e.max()
    m = np.arange(max_e + 1)  # shape (max_e+1,)

    # 广播计算f^m:shape (n_rows, max_e+1)
    f_pow_m = f[:, None] ** m
    # 计算p的完整序列,最后取每行第e[i]位(即最后一个有效位置)
    p_full = d[:, None] * (f_pow_m - 1) / (f[:, None] - 1)
    p_last = p_full[np.arange(len(e)), e]

    # 计算s序列,同样取最后一位
    s_full = pr * (1 - p_full / 100)
    s_last = s_full[np.arange(len(e)), e]

    # 处理q序列:首项是a,后面是b*g^so(so从0到e-1)
    # 生成so序列:shape (max_e,)
    so = np.arange(max_e)
    g_pow_so = g[:, None] ** so  # shape (n_rows, max_e)
    # 构造q_full:首列是a,后面是b*g_pow_so,长度为max_e+1
    q_full = np.hstack([a[:, None], b[:, None] * g_pow_so])
    # 计算累积和r_full,取最后一位
    r_full = np.cumsum(q_full, axis=1)
    r_last = r_full[np.arange(len(e)), e]

    # 计算t_full和u_full,取u的最后一位
    t_full = q_full / s_full
    u_full = np.cumsum(t_full, axis=1)
    u_last = u_full[np.arange(len(e)), e]

    # 计算v_last、w_last、x_last
    v_last = r_last / u_last
    w_last = v_last * (1 + c / 100)
    x_last = ((w_last - s_last) / s_last) * 100

    # 计算y和z_last
    y = a * (c / 100)
    z_last = r_last * (c / 100)

    # 将结果添加到原表
    table1['p_last'] = p_last
    table1['x_last'] = x_last
    table1['y'] = y
    table1['z_last'] = z_last

    return table1

# 测试调用
result_table = vectorized_calculate(table1)
print(result_table)

代码说明

  1. 广播机制:将一维数组转为二维(通过[:, None]),与长度为max_e+1的序列进行广播运算,实现批量计算。
  2. 索引提取有效结果:由于每行的e值不同,通过np.arange(len(e)), e直接提取每行对应长度的最后一个有效结果。
  3. 无循环批量计算:所有操作均为numpy原生批量运算,彻底避免逐行循环,效率远高于apply,可支撑超大规模数据处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:21:11