【问题标题】:Efficient calculation across dictionary consisting of thousands of correlation matrizes跨由数千个相关矩阵组成的字典的高效计算
【发布时间】:2020-09-23 02:48:17
【问题描述】:

基于来自 20 种资产的每日观察的大型数据集,我创建了一个包含(滚动)相关矩阵的字典。我使用日期索引作为字典的键。

我现在要做的(以一种有效的方式)是比较字典中的所有相关矩阵并将结果保存在一个新矩阵中。这个想法是比较一段时间内的相关结构。

import pandas as pd
import numpy as np
from scipy.cluster.hierarchy import linkage
from scipy.cluster.hierarchy import cophenet


key_list = dict_corr.keys()

# Create empty matrix
X = np.empty(shape=[len(key_list),len(key_list)])

key1_index = 0
key2_index = 0
for key1 in key_list:


    # Extract correlation matrix from dictionary
    corr1_temp = d[key1]

    # Transform correlation matrix into distance matrix
    dist1_temp = ((1-corr1_temp)/2.)**.5

    # Extract hierarchical structure from distance matrix
    link1_temp = linkage(dist1_temp,'single') 

    for key2 in key_list:

        corr2_temp = d[key2]
        dist2_temp = ((1-corr2_temp)/2.)**.5
        link2_temp = linkage(dist2_temp,'single')

        # Compare hierarchical structure between the two correlation matrizes -> results in 2x2 matrix
        temp = np.corrcoef(cophenet(link1_temp),cophenet(link2_temp))

        # Extract from the resulting 2x2 matrix the correlation
        X[key1_index, key2_index] = temp[1,0]

        key2_index =+ 1

    key1_index =+1

我很清楚使用两个 for 循环可能是效率最低的方法。

所以我很感谢任何有用的评论如何加快计算!

最好的

【问题讨论】:

    标签: python pandas numpy scipy hierarchical-clustering


    【解决方案1】:

    您可以查看 itertools,然后插入代码以计算在单个 for 循环中调用的函数 (compute_corr) 中的相关性:

    import itertools
    for key_1, key_2 in itertools.combinations(dict_corr, 2):
        correlation = compute_corr(key_1, key_2, dict_corr)
        #now store correlation in a list 
    

    如果您关心订单,请使用itertools.permutations(dict_corr, 2) 而不是组合。

    编辑

    由于您想要所有可能的键组合(也是一个键本身),您应该使用itertools.product。

    l_corr = [] #list to store all the output from the function
    for key_1, key_2 in itertools.product(key_list, repeat= 2 ):
        l_corr.append(compute_corr(key_1, key_2, dict_corr))
    

    现在l_corr 将会很长:len(key_list)*len(key_list)。 您可以通过这种方式将此列表转换为矩阵:

    np.array(l_corr).reshape(len(key_list),len(key_list))
    

    虚拟示例:

    def compute_corr(key_1, key_2, dict_corr):
        return key_1 * key_2 #dummy result from the function
    
    dict_corr={1:"a",2:"b",3:"c",4:"d",5:"f"}
    key_list = dict_corr.keys()
    
    l_corr = []
    for key_1, key_2 in itertools.product(key_list, repeat= 2 ):
        print(key_1, key_2)
        l_corr.append(compute_corr(key_1, key_2, dict_corr))
    

    组合:

    1 1
    1 2
    1 3
    1 4
    1 5
    2 1
    2 2
    2 3
    2 4
    2 5
    3 1
    3 2
    3 3
    3 4
    3 5
    4 1
    4 2
    4 3
    4 4
    4 5
    5 1
    5 2
    5 3
    5 4
    5 5
    

    创建最终矩阵:

    np.array(l_corr).reshape(len(key_list),len(key_list))
    
    array([[ 1,  2,  3,  4,  5],
           [ 2,  4,  6,  8, 10],
           [ 3,  6,  9, 12, 15],
           [ 4,  8, 12, 16, 20],
           [ 5, 10, 15, 20, 25]])
    

    如果我错过了什么,请告诉我。希望对你有帮助

    【讨论】:

    • 这很有帮助,谢谢。只有一个后续问题:我想创建一个矩阵而不是一个列表来可视化所有组合。有什么建议如何实现吗?
    • 假设您的字典中有 5 个键。那么你想要一个包含所有相关性的 5x5 矩阵吗?在这种情况下,您还将拥有每个矩阵与其自身之间的相关性(当键相同时)对吗?并且在比较例如 1vs2 和 2vs1 时你会得到相同的结果
    • 正确。正是我要找的!
    • 快速跟进问题:代码完美运行。只是想知道您是否有任何建议/想法如何显着加快整个过程?
    • 恐怕这里的速度瓶颈是调用计算相关性的函数。如果假设 1vs2 与 2vs1 之间的相关性相同,您可以简单地复制该值而不是再次计算它。当然,这适用于所有对。
    猜你喜欢
    • 1970-01-01
    • 2018-08-01
    • 2016-08-04
    • 2012-10-01
    • 2016-02-15
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多