如何优化大型Pandas DataFrame中所有列对的滚动相关性计算
如何优化大型Pandas DataFrame中所有列对的滚动相关性计算
你的问题我太懂了——当列数上百的时候,遍历每一对列跑rolling.corr()确实慢得让人头疼,本质原因是每一次循环都在重复计算滚动均值、方差这些基础统计量,完全是做无用功。咱们换个思路,利用Pearson相关系数的数学公式,把重复计算的部分一次性搞定,效率能提升好几个量级。
核心优化思路:复用滚动统计量
Pearson相关系数可以拆解成下面的形式:
$$\text{corr}(X,Y) = \frac{\text{Cov}(X,Y)}{\text{std}(X) \times \text{std}(Y)}$$
而协方差又可以用均值推导:
$$\text{Cov}(X,Y) = E[XY] - E[X]E[Y]$$
基于这个公式,我们只需要一次性计算所有列的滚动均值、滚动平方均值、滚动交叉乘积均值,就能通过向量化运算直接生成所有列对的相关性,不用再逐对循环。
优化后的代码实现
import pandas as pd import numpy as np import itertools def pairwise_rolling_correlations_vectorized(df, window_size, min_periods=None): # 处理min_periods参数,默认和rolling.corr行为一致 roll_kwargs = {"window": window_size} if min_periods is not None: roll_kwargs["min_periods"] = min_periods # 1. 计算所有列的基础滚动统计量 mu = df.rolling(**roll_kwargs).mean() # 滚动均值 mu_sq = (df ** 2).rolling(**roll_kwargs).mean() # 滚动平方均值 std = np.sqrt(mu_sq - mu ** 2) # 滚动标准差 # 2. 计算所有列对的滚动乘积均值(E[XY]) # df[:, None] 把DataFrame转为(n行, m列, 1),和原df广播相乘得到(n行, m列, m列)的结果 cross_prod = df[:, None] * df cross_mu = cross_prod.rolling(**roll_kwargs).mean() # 3. 推导协方差和相关系数 cov = cross_mu - mu[:, None] * mu # Cov(X,Y) = E[XY] - E[X]E[Y] corr = cov / (std[:, None] * std) # 相关系数 = 协方差 / (标准差乘积) # 4. 筛选出和原方法一致的列对(只保留col1 < col2的组合,避免重复) column_pairs = list(itertools.combinations(df.columns, 2)) corr = corr[[pair for pair in column_pairs]] return corr
为什么这个方法更快?
原来的 naive 方法需要对每一对列单独执行滚动计算,时间复杂度是 $O(m^2n)$(m是列数,n是行数);而优化后的方法只需要几次全局滚动计算,再做一次向量化矩阵运算,时间复杂度降到 $O(mn)$——当列数是100的时候,理论上能快100倍左右,实际测试中差距会更明显。
举个测试例子:生成10000行、100列的随机DataFrame,窗口大小30:
np.random.seed(42) df = pd.DataFrame(np.random.randn(10000, 100), columns=[f'col{i}' for i in range(100)]) # 原方法:大概需要30-40秒(取决于机器) %timeit pairwise_rolling_correlations_naive(df, 30) # 优化方法:只需要2-3秒 %timeit pairwise_rolling_correlations_vectorized(df, 30)
额外细节处理
- NaN值兼容:和原方法的
rolling.corr()行为一致,默认只有当窗口内非NaN值数量等于窗口大小时才计算,否则返回NaN;如果需要调整,可以传入min_periods参数。 - 内存问题:如果列数特别多(比如500列,会生成25万列的中间结果),可以考虑分块处理——把列分成若干组,每组和其他组计算相关性后再合并结果,避免内存溢出。
备注:内容来源于stack exchange,提问作者micycle
相关产品推荐
相关产品推荐

