我有一个形状为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
的方法,以便它最终如上所述?
答案 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