【问题标题】:Can I increase the compution speed of correlation analysis between vast time-series data?我可以提高海量时间序列数据之间相关性分析的计算速度吗?
【发布时间】:2016-04-27 21:13:08
【问题描述】:

首先,我将介绍我的目标和实现它的代码

  1. VALUE 是一个 3-d numpy 数组,表示 2-d 区域的时间变化。 (例如value[:1000,2,3] = list[网格(X = 3,Y = 2)的值从0到1000s]。)

    在我的实际工作中,VALUE 的形状是 (2812, 75, 90) ps:“2812”是 4 个月的总小时数

  2. 我称为 SELECT 的某个点表示一个有趣的点,我将对该区域中的每个网格进行相关性分析。

    SELECT 是一个 pandas 数据框,包括每个有趣点的 X 和 Y

  3. COV 是一个 3-d 数组作为计数矩阵,记录每个 SELECT 点与每个网格点的相关程度

    设置截止皮尔逊系数 rc = 0.75,
    对于 SELECTt,
    如果 r(i,j) > rc ==> cov[t,i,j] = 1,否则 cov[t,i,j] = 0

这是我的代码,但有点慢。我认为该过程的某些部分可以改进:

start = timeit.default_timer()
### SELECT is a pandas dataframe including each interesting point's X and Y
cov = np.zeros(len(SELECT)*VALUE.shape[1]*VALUE.shape[2]).reshape(len(SELECT), VALUE.shape[1],VALUE.shape[2])
for t in range(0,len(SELECT),1):
    select_grid = pd.DataFrame(VALUE[:,SELECT.Y.iloc[t],SELECT.X.iloc[t]])
for i in range(0,VALUE.shape[1],1):
    for j in range(0,VALUE.shape[2],1):
        data_grid = pd.DataFrame(VALUE[:,i,j])
         ## Using corr to compute the correlation r
        r_sg  = select_grid[0].corr(data_grid[0])
        if r_sg > 0.75:
            cov[t,i,j] = 1

end = timeit.default_timer()                
print end - start                                                                                                        

【问题讨论】:

  • 您是否尝试过运行分析器来查看时间花在了哪里?例如line_profiler 中描述的this article,只需向下滚动到“逐行......”部分。可能有助于阐明可以改进的地方。
  • 你能给出len(SELECT), VALUE.shape[1], VALUE.shape[2]end - start 的幅度来估计可能的改进吗? ds_grid 是什么?数据链接也是一个很好的工具。
  • 谢谢!我不知道timing context manager。如果可以的话,我会学习的。

标签: python numpy pandas scipy correlation


【解决方案1】:

您的工作很耗时:SELECT 中的每个样本大约需要一秒钟。

  • 矢量化不会给您带来很大的改进,因为耗时的 corr 函数在内部循环中。

  • 但是,您可以使用更轻量的代码,pandas 在这里并不是绝对必要的。例如:

    VALUE=random((2812,5,5))
    select=pd.DataFrame(randint(0,5,(10,2)))
    ....
    for (x,y) in select.values:
    ....
         r=np.corrcoef(VALUE[:,x,y],VALUE[:,i,j])[0,1]
    ....
    

[0,1] 用于在这里选择r,因为 corrcoef 计算的是一个 2x2 数组。

  • 您可以做的第一个优化是使用 numpy 数组而不是 DataFrames 以获得 2 倍的 corr 计算增益。

    DFexample = pd.DataFrame(VALUE[:,0,:])
    
    In [19]: %timeit np.corrcoef(VALUE[:,0,0],VALUE[:,0,1]) 
    1000 loops, best of 3: 556 µs per loop
    
    In [20]: %timeit DFexample[0].corr(DFexample[1])
    1000 loops, best of 3: 1.09 ms per loop
    
  • 另一个是预先计算意味着 ans std,因为 r(x,y) = (<xy>-<x><y>)/σx/σy 获得 3 倍增益:

    In [24]: s=VALUE.std(axis=0)  # 1 second
    
    In [25]: m=VALUE.mean(axis=0) # 2 second
    
    In [26]: %timeit ((VALUE[:,0,0]*VALUE[:,0,1]).mean() -m[0,1]*m[0,0])/s[0,0]/s[0,1]
    10000 loops, best of 3: 172 µs per loop
    
    In [31]: allclose(((VALUE[:,0,0]*VALUE[:,0,1]).mean() -m[0,1]*m[0,0])/s[0,0]/s[0,1],\
    DFexample[0].corr(DFexample[1]))
    Out[31]: True
    

因此您至少可以赢得 6 倍系数

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-22
    • 2014-04-12
    • 1970-01-01
    • 2019-11-03
    • 2018-10-21
    • 2019-12-15
    • 1970-01-01
    相关资源
    最近更新 更多