在python/numpy中计算索引的特定组合之间的相关性 *only*

gv8xihay  于 12个月前  发布在  Python
关注(0)|答案(1)|浏览(91)

我试图计算存储在2D numpy数组中的变量之间的一些相关性(整数值,维数:n_variables * n_observations)。
例如:

data = np.array([
    [1,3,7,5,6],
    [2,3,4,5,2],
    [3,3,9,5,10],
    [4,3,4,8,6],])

因此,我有一个“掩码数组”(布尔值,维数:n_variable * n_variables)表示我感兴趣的变量对,它没有先验模式。每个变量也可以有不同数量的occupancy。
例如:V1和V2,V1和V3,V3和V4。

potential_corr =  np.array([
    [0,1,1,0],
    [1,0,0,0],
    [1,0,0,1],
    [0,0,1,0],])

有没有一种方法可以只为这些特定的索引组合计算相关性(或应用其他函数)?
我看到的矩阵有超过10万个变量和相同的观测顺序,因此我真的试图在相关性计算之前使用这个过滤器,以优化计算时间和内存。
我真的不习惯非主流的numpy用法,也没有找到实现这种“稀疏”计算的函数。我想我可以使用take_沿着_axis,但如果我没有弄错的话,每个变量将被存储与它存在的组合数量一样多的次数。这看起来不像是个好主意,记忆明智的。
当然,我正在寻找与我的问题相关的任何解决方案,如果其他数据格式合适,我绝对不想使用numpy数组。
非常感谢你的帮助!
雷米

3vpjnl9f

3vpjnl9f1#

一种可能的解决方案,它只计算平均值和标准差 * 一次:

def calculate_corr_for_pairs(data, mask):
    n_vars, n_obs = data.shape

    means = np.mean(data, axis=1)
    stds = np.std(data, axis=1, ddof=1)

    results = []

    pairs_idx = np.nonzero(mask)

    for i, j in zip(*pairs_idx):
        xi = data[i, :] - means[i]
        xj = data[j, :] - means[j]
        corr = np.sum(xi * xj) / ((n_obs - 1) * stds[i] * stds[j])
        results.append({f'V_{i+1}, V_{j+1}': corr})

    return results

idx = np.triu(potential_corr)

calculate_corr_for_pairs(data, idx)

另一种可能的解决方案(但不如前一种有效,因为它重复了平均值和标准差的计算):

idx = np.nonzero(np.triu(potential_corr))
[{f'V_{i+1}, V_{j+1}': np.corrcoef(data[i,:], data[j,:])[0,1]} 
 for i,j in zip(idx[0], idx[1])]

输出量:

[{'V_1, V_2': 0.44585082870893733},
 {'V_1, V_3': 0.8763704002132351},
 {'V_3, V_4': 0.26382242650554316}]

相关问题