我有一个矩阵上三角的列和值的列表,我想将其转换为对称矩阵。例如,我有
UpperTriangle = [[[0, 5], [6.0, 4.0]],
[[1, 3], [9.0, 6.0]],
[[2, 4, 6], [9.0, 6.0, 6.0]],
[[3], [4.0]],
[[4, 6], [4.0, 4.0]],
[[5], [2.6666666666666665]],
[[6], [4.0]]]
我想将其转换为
Symmetric = [[[0, 5], [6.0, 4.0]],
[[1, 3], [9.0, 6.0]],
[[2, 4, 6], [9.0, 6.0, 6.0]],
[[1, 3], [6.0, 4.0]],
[[2, 4, 6], [6.0, 4.0, 4.0]],
[[0, 5], [4.0, 2.6666666666666665]],
[[2, 4, 6], [6.0, 4.0, 4.0]]]
第一个列表属于矩阵的第一行,列表中的第一个列表给出列索引,第二个列表给出与列索引有关的值。第二个列表属于第二行,依此类推。在上面的示例中(row = 0,column = 0)的值为6.0,(row = 0,column = 5)的值为4.0,(row = 1,column = 1)的值为9.0,(row = 1,column = 3)值6.0。
一种方法是创建一个numpy矩阵,然后使用以下代码创建一个对称矩阵。
W = np.maximum( A, A.transpose() )
但这是不可行的,因为实际问题涉及一个包含350,000行和列的矩阵,构建一个numpy矩阵A会占用太多内存,而转换它会花费太多时间。
将UpperTriangle转换为Symmetric而无需借助构建numpy矩阵的最快Python方法是什么(使用Python 2.7)? (在合理的内存范围内)。
问题是在使用IBM的Cplex Python API的情况下出现的,您需要在其中插入对称矩阵以设置二次方。
import cplex
my_prob = cplex.Cplex()
my_prob.objective.set_quadratic(Symmetric)
my_prob.solve()
答案 0 :(得分:1)
此处输入的CSR表示非常方便。在考虑每一行时,您当然会了解对称矩阵的列。当您到达每一行时,您已经已经知道了其上三角形式中省略的所有列的内容。您甚至可以按照它们在该行中出现的顺序来了解这些值!
这只是编程上的一个简单问题:
def sym(up): # alters 'up' in place
pfx=[([],[]) for _ in up] # to be added to each row
for r,((cc,vv),(pc,pv)) in enumerate(zip(up,pfx)):
for c,v in zip(cc,vv):
if c>r: # store off-diagonal for later row
cr,cv=pfx[c]
cr.append(r); cv.append(v)
cc[:0]=pc; vv[:0]=pv # prepend to preserve order