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

高效计算时间序列相关性的性能优化方案咨询

产品销售相关性计算的性能优化方案求助

数据格式

我的销售数据格式如下:

[Date, Product, Sales]
01-01, A, 3
01-02, A, 0
01-03, A, 2
...
01-01, Z, 10
01-02, Z, 11
01-03, Z, 13

需求与当前实现问题

我需要找出销售模式高度相似或相异的产品,当前采用计算每对产品销售额皮尔逊相关系数的方案,代码如下:

df = pd.DataFrame(..., columns=['Date', 'Product', 'Sales'])
products = df.Product.unique()
correlations = []

for i in range(len(products)):
    a = df[df.Product == products[i]]

    for j in range(i+1, len(products)):
        b = df[df.Product == products[j]]
        
        # 内连接确保日期一致(部分产品存在数据缺失)
        merged = pd.merge(a, b, on='Date', how='inner')
        
        # 计算皮尔逊相关系数
        corr = merged['Sales_x'].corr(merged['Sales_y'])
        correlations.append((products[i], products[j], corr))

目前有大约10k个产品,内连接后日期重叠最多约2k个。上述代码时间复杂度为O(产品数²×日期数),当前运行时长约30小时,添加线程后性能无明显提升。希望优化代码以高效计算产品间销售相关性,后续计划为每个产品选取相关性Top和Bottom X的产品用于决策(比如分析产品蚕食效应)。

补充示例

假设数据包含3个产品A、B、C:

[Date, Product, Sales]
01-01, A, 3
01-02, A, 0
01-03, A, 2

01-01, B, 2
01-02, B, 0
01-03, B, 3

01-01, C, 0
01-02, C, 4
01-03, C, 0 

A与B销售模式高度相似,皮尔逊相关系数接近1;A与C销售模式完全相反,相关系数接近-1,这类关系是我需要分析的核心。


优化方案

1. 数据重塑为宽表,利用矩阵运算加速

Python循环的效率极低,直接用pandas的向量化/矩阵运算功能,底层是C实现的优化代码,能把运行时间压缩到分钟级:

import pandas as pd

# 将长表转为宽表:行=日期,列=产品,值=销售额
wide_df = df.pivot(index='Date', columns='Product', values='Sales')

# 自动计算所有产品对的皮尔逊相关系数矩阵
# 注:计算时会自动忽略任意一方数据缺失的日期,等价于手动内连接的逻辑
corr_matrix = wide_df.corr(method='pearson')

这个方案直接跳过了Python层面的双重循环,把计算逻辑交给底层优化的矩阵运算,性能提升几个数量级。

2. 内存友好的替代方案(scipy)

如果宽表内存占用过高,可使用scipy的pdist计算两两相关系数,同样是底层优化的实现:

import pandas as pd
from scipy.spatial.distance import pdist, squareform

wide_df = df.pivot(index='Date', columns='Product', values='Sales')
# 转置为产品×日期的矩阵,适配pdist的输入要求
product_sales = wide_df.T.values

# pdist的correlation metric返回的是(1-皮尔逊相关系数),转换回相关系数
corr_dist = pdist(product_sales, metric='correlation')
corr_matrix = 1 - squareform(corr_dist)
# 转成DataFrame方便后续处理
corr_matrix = pd.DataFrame(corr_matrix, index=wide_df.columns, columns=wide_df.columns)

3. 高效提取Top/Bottom X相关产品

不需要保存完整的10k×10k相关矩阵,直接遍历每个产品提取目标结果,节省内存:

top_x = 5  # 自定义需要的Top相似产品数量
bottom_x = 5  # 自定义需要的Bottom相异产品数量
product_correlations = {}

for product in corr_matrix.columns:
    # 排除产品自身的相关系数(值为1)
    corr_series = corr_matrix[product].drop(product)
    # 获取Top X相似产品
    top_similar = corr_series.nlargest(top_x).to_dict()
    # 获取Bottom X相异产品
    top_dissimilar = corr_series.nsmallest(bottom_x).to_dict()
    product_correlations[product] = {
        'top_similar': top_similar,
        'top_dissimilar': top_dissimilar
    }

4. 并行计算的正确打开方式

之前加线程无提升是因为Python GIL限制,CPU密集型任务要用多进程:

import pandas as pd
from joblib import Parallel, delayed
import numpy as np

wide_df = df.pivot(index='Date', columns='Product', values='Sales')

# 将产品列表分块,避免单进程内存压力过大
product_chunks = np.array_split(wide_df.columns, 8)  # 分8块,可根据CPU核心数调整

def compute_corr_chunk(chunk):
    # 计算当前块与全量产品的相关系数
    return wide_df[chunk].corrwith(wide_df)

# 多进程并行计算
chunk_results = Parallel(n_jobs=-1)(delayed(compute_corr_chunk)(chunk) for chunk in product_chunks)
# 合并结果为完整的相关矩阵
corr_matrix = pd.concat(chunk_results, axis=1)

注:如果用pandas/scipy的原生corr已经足够快,这个方案可能提升有限,但在超大规模数据下能进一步缩短时间。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 21:30:24