快速重构多指数协方差到2D协方差(维持C顺序)

时间:2017-09-30 18:18:27

标签: python arrays reshape

问题

我有一个形状为S的数组(a,b,c,d,a,b,c,d),它表示形状(a,b,c,d)数据的协方差矩阵。 我必须将S转换为形状(a*b*c*d, a*b*c*d),其中索引转换是C顺序,即等效代码是,

S_out = np.zeros([a*b*c*d, a*b*c*d],dtype=float)
for h1 in range(a*b*c*d):
    i1,j1,k1,l1 = np.unravel_index(h1, (a,b,c,d))
    for h2 in range(h1,a*b*c*d):
        i2,j2,k2,l2 = np.unravel_index(h2, (a,b,c,d))
        S_out[h1,h2] = S[i1,j1,k1,l1,i2,j2,k2,l2]
        S_out[h2,h1] = S_out[h1,h2]

转置对称性是因为它是一个协方差矩阵。

要构建测试S,您可以使用:

S_ = np.random.uniform(size=[a*b*c*d, a*b*c*d])
S_ = S_.dot(S_.T)#to symmetrise
S_test = np.zeros([a,b,c,d,a,b,c,d], dtype=float)
for h1 in range(a*b*c*d):
    i1,j1,k1,l1 = np.unravel_index(h1, (a,b,c,d))
    for h2 in range(a*b*c*d):
        i2,j2,k2,l2 = np.unravel_index(h2, (a,b,c,d))
        S_test[i1,j1,k1,l1,i2,j2,k2,l2] = S_[h1,h2]

问题

是否有一种快速重新排序S的方法,以便它最终如上所述?

1 个答案:

答案 0 :(得分:0)

在第二个for循环中,从h1而不是0开始。这导致S_out不等于S.我将其更改为从0开始,然后如果我展平两个数组,则S_out和S相等。如果这是你的意思,你可以简单地重塑S,如代码片段的最后两行所示。

import numpy as np

a, b, c, d = 2, 3, 4, 5
S = np.random.random([a,b,c,d,a,b,c,d])
S_out = np.zeros([a*b*c*d, a*b*c*d], dtype=float)
for h1 in range(a*b*c*d):
    i1,j1,k1,l1 = np.unravel_index(h1, (a,b,c,d))
    for h2 in range(a*b*c*d):
        i2,j2,k2,l2 = np.unravel_index(h2, (a,b,c,d))
        S_out[h1,h2] = S[i1,j1,k1,l1,i2,j2,k2,l2]
        S_out[h2,h1] = S_out[h2,h1]


# Seems like the order is not changing? Is this intended?
print('Flatted is same as input: ', (S.flatten() == S_out.flatten()).all())

# If so, we can just reshape
S_out2 = S.reshape(a*b*c*d, a*b*c*d)
print('Reshape gives same result: ', (S_out == S_out2).all())

输出:

Flatted is same as input:  True
Reshape gives same result:  True