如何优化基于二分法的Pandas方程求解函数以提升速度?
优化二分法求解参数n的性能问题及时间复杂度解析
问题背景
需要实现函数求解方程参数n(进而推导p、q、r),其中x、y、z为已知量。当前采用二分法寻找满足±0.0001公差的n值,编写的Python函数如下:
# game is a series with implied probabilites for each outcome in a football match def logfunc(game): n_range = [1, 0] n = 0.5 probs = 1 / game expression = (probs ** (1/n)).sum() while not math.isclose(expression, 1, abs_tol=0.0001): if expression > 1: n_range[0] = n else: n_range[1] = n n = (n_range[0] + n_range[1]) / 2 expression = (probs ** (1/n)).sum() return game[ODDS] ** (1/n)
但处理包含30万行的DataFrame时,该函数运行速度极慢。
附加问题
二分法的时间复杂度为O(log n),此处的n具体指什么?是否是0到1区间内按0.0001间隔划分的数值数量?
性能优化方案
1. 向量化运算替代逐行循环
当前函数逐行(单Series)处理DataFrame是性能瓶颈的核心原因。Pandas/NumPy的核心优势是向量化批量运算,应将整个DataFrame作为输入,一次性处理所有行:
- 预先对全量数据计算
probs = 1 / df(向量化除法,避免逐行计算) - 实现向量化的二分逻辑,用数组操作替代Python循环
2. 固定迭代次数减少判断开销
要将初始区间[0,1]缩小到0.0001的精度,每次迭代区间长度减半,所需迭代次数为log2(1/0.0001) ≈ 14次。直接固定迭代14次,无需每次调用math.isclose判断,可减少额外开销。
3. 用NumPy加速数值计算
将Pandas对象转换为NumPy数组,**幂运算和sum求和在NumPy中的执行效率远高于Pandas的Series操作。
优化后的示例代码:
import numpy as np import pandas as pd def vectorized_logfunc(df): # 转换为NumPy数组,提升运算速度 probs = 1 / df.values # 初始化所有行的搜索区间和初始n值 n_low = np.zeros(df.shape[0]) n_high = np.ones(df.shape[0]) n = np.full(df.shape[0], 0.5) # 固定迭代14次,满足0.0001精度要求 for _ in range(14): # 向量化计算每行的表达式值 expr = (probs ** (1/n[:, np.newaxis])).sum(axis=1) # 批量更新区间 mask = expr > 1 n_low[mask] = n[mask] n_high[~mask] = n[~mask] # 更新n值 n = (n_low + n_high) / 2 # 批量计算最终结果并转回DataFrame result = df.values ** (1/n[:, np.newaxis]) return pd.DataFrame(result, columns=df.columns)
调用方式:result_df = vectorized_logfunc(original_df)
附加问题解答
二分法时间复杂度O(log n)中的n,本质是初始搜索区间长度与目标精度的比值,即把区间缩小到符合精度要求所需的“缩放倍数”。
- 它不是0到1区间按0.0001划分的数值数量(虽然该数量为10000,
log2(10000)≈14刚好对应所需迭代次数),而是初始区间长度除以最终允许的区间长度的商。比如初始区间长度为1,目标精度0.0001,商为1/0.0001=10000,时间复杂度表现为O(log(10000)),属于固定常数级的迭代次数。
内容的提问来源于stack exchange,提问作者T0rvadaL
相关产品推荐
相关产品推荐

