如何加速超大型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)
代码说明
- 广播机制:将一维数组转为二维(通过
[:, None]),与长度为max_e+1的序列进行广播运算,实现批量计算。 - 索引提取有效结果:由于每行的
e值不同,通过np.arange(len(e)), e直接提取每行对应长度的最后一个有效结果。 - 无循环批量计算:所有操作均为numpy原生批量运算,彻底避免逐行循环,效率远高于
apply,可支撑超大规模数据处理。
内容的提问来源于stack exchange,提问作者wkamer
相关产品推荐
相关产品推荐

