我有一个形状为A
的大型(n, n, 3, 3)
矩阵n
约为5000
。现在我想找到矩阵A
的反转和转置:
import numpy as np
A = np.random.rand(1000, 1000, 3, 3)
identity = np.identity(3, dtype=A.dtype)
Ainv = np.zeros_like(A)
Atrans = np.zeros_like(A)
for i in range(1000):
for j in range(1000):
Ainv[i, j] = np.linalg.solve(A[i, j], identity)
Atrans[i, j] = np.transpose(A[i, j])
有更快,更有效的方法吗?
答案 0 :(得分:7)
这取自我的一个项目,我也在许多3x3矩阵上进行矢量化线性代数。
请注意,只有一个超过3的循环;不是n上的循环,因此代码在重要维度中被矢量化。我不想保证这与C / numba扩展相比如何做同样的事情,性能明智。这可能会大大加快,但至少这会将环路吹过水中。
def adjoint(A):
"""compute inverse without division by det; ...xv3xc3 input, or array of matrices assumed"""
AI = np.empty_like(A)
for i in xrange(3):
AI[...,i,:] = np.cross(A[...,i-2,:], A[...,i-1,:])
return AI
def inverse_transpose(A):
"""
efficiently compute the inverse-transpose for stack of 3x3 matrices
"""
I = adjoint(A)
det = dot(I, A).mean(axis=-1)
return I / det[...,None,None]
def inverse(A):
"""inverse of a stack of 3x3 matrices"""
return np.swapaxes( inverse_transpose(A), -1,-2)
def dot(A, B):
"""dot arrays of vecs; contract over last indices"""
return np.einsum('...i,...i->...', A, B)
A = np.random.rand(2,2,3,3)
I = inverse(A)
print np.einsum('...ij,...jk',A,I)
答案 1 :(得分:3)
:
在ipython中测试了一下:
In [1]: import numpy
In [2]: x = numpy.ones((5,6,3,4))
In [3]: numpy.transpose(x,(0,1,3,2)).shape
Out[3]: (5, 6, 4, 3)
所以你可以做到
Atrans = numpy.transpose(A,(0,1,3,2))
转换第二维和第三维(同时保留第0和第1维)
反转的:
http://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.inv.html#numpy.linalg.inv
的最后一个例子可以一次计算几个矩阵的逆:
from numpy.linalg import inv
a = np.array([[[1., 2.], [3., 4.]], [[1, 3], [3, 5]]])
>>> inv(a)
array([[[-2. , 1. ],
[ 1.5, -0.5]],
[[-5. , 2. ],
[ 3. , -1. ]]])
所以我想在你的情况下,可以用
完成反演Ainv = inv(A)
并且它将知道最后两个维度是它应该反转的维度,并且第一个维度就是您堆叠数据的方式。这应该快得多
速度差异
转置:你的方法需要3.77557015419秒,我的需要2.86102294922e-06秒(加速超过100万次)
对于反转:我猜我的numpy版本不够高,无法尝试使用(n,n,3,3)形状的numpy.linalg.inv技巧,看看那里的加速(我的版本是1.6.2,我基于我的解决方案的文档是1.8,但它应该工作在1.8,如果其他人可以测试吗?)
答案 2 :(得分:2)
Numpy拥有array.T
属性,这是transpose的快捷方式。
对于反转,您使用np.linalg.inv(A)
。
答案 3 :(得分:0)
由wim A.发布。我也在矩阵上工作。 e.g。
print(A.I)
答案 4 :(得分:-1)
对于numpy-matrix对象,使用matrix.getI。 例如
Data Type = grid
Dimensions = 0 1
I Dimension = 1 to 73 Linear 0 5
J Dimension = 1 to 46 Linear -90 4
Sizes = 73 46 3358
Undef value = -2.56e+33
Undef count = 1763 Valid count = 1595
Min, Max = 243.008 302.818
Cmin, cmax, cint = 245 300 5
Stats[sum,sumsqr,root(sumsqr),n]: 452778 1.29046e+08 11359.8 1595
Stats[(sum,sumsqr,root(sumsqr))/n]: 283.874 80906.7 284.441
Stats[(sum,sumsqr,root(sumsqr))/(n-1)]: 284.052 80957.4 284.53
Stats[(sigma,var)(n)]: 17.9565 322.437
Stats[(sigma,var)(n-1)]: 17.9622 322.64
Contouring: 245 to 300 interval 5