Python 反转numpy中的非零子矩阵,返回原始形状的矩阵
我有一个矩阵,有些行和列等于零,所以它是不可逆的。Python 反转numpy中的非零子矩阵,返回原始形状的矩阵,python,arrays,numpy,matrix-inverse,Python,Arrays,Numpy,Matrix Inverse,我有一个矩阵,有些行和列等于零,所以它是不可逆的。 我需要得到一个非零子矩阵,这样逆矩阵就和原始矩阵有相同的结构。 预期的行为如下所示: >>>test array([[1, 0, 0, 2], [0, 0, 0, 0], [0, 0, 0, 0], [3, 0, 0, 4]]) >>>get_nonzero(test) array([[1, 2], [3, 4]]) >>>np.lin
我需要得到一个非零子矩阵,这样逆矩阵就和原始矩阵有相同的结构。
预期的行为如下所示:
>>>test
array([[1, 0, 0, 2],
[0, 0, 0, 0],
[0, 0, 0, 0],
[3, 0, 0, 4]])
>>>get_nonzero(test)
array([[1, 2],
[3, 4]])
>>>np.linalg.inv(nonzero)
array([[-2. , 1. ],
[ 1.5, -0.5]])
>>>restore_shape(inv_matrix)
array([[-2. , 0. , 0. , 1. ],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[ 1.5, 0. , 0. , -0.5]])
>>>pd.DataFrame(original).loc[~bool_index, ~bool_index].values
array([[1, 2],
[3, 4]])
也许这与我最初通过将原始矩阵的行和列归零得到test
矩阵有关,所有元素都是非零的,布尔索引如下:
>>>bool_index
array([False, True, True, False])
>>>original[bool_index, :] = 0
>>>original[:, bool_index] = 0
>>>original
array([[1, 0, 0, 2],
[0, 0, 0, 0],
[0, 0, 0, 0],
[3, 0, 0, 4]])
我通过首先将原始矩阵转换为pandasDataFrame
,并使用.loc
的布尔数组进行索引,实现了从原始矩阵获取非零子矩阵,如下所示:
>>>test
array([[1, 0, 0, 2],
[0, 0, 0, 0],
[0, 0, 0, 0],
[3, 0, 0, 4]])
>>>get_nonzero(test)
array([[1, 2],
[3, 4]])
>>>np.linalg.inv(nonzero)
array([[-2. , 1. ],
[ 1.5, -0.5]])
>>>restore_shape(inv_matrix)
array([[-2. , 0. , 0. , 1. ],
[ 0. , 0. , 0. , 0. ],
[ 0. , 0. , 0. , 0. ],
[ 1.5, 0. , 0. , -0.5]])
>>>pd.DataFrame(original).loc[~bool_index, ~bool_index].values
array([[1, 2],
[3, 4]])
但是,我不确定如何才能有效地将倒排数组恢复到原始形状。要使用您建议的函数格式,并假设您的输入矩阵可以生成N*N矩阵,以下操作有效:
import numpy as np
def get_nonzero(t1):
t2 = t1[t1 != 0]
size = int(np.sqrt(len(t2)))
return t2.reshape(size, size)
def restore_shape(t1, t3):
t4 = np.zeros(t1.shape)
idx_non_zeros = np.nonzero(t1)
for i, elt in enumerate(t3.flatten()):
t4[idx_non_zeros[0][i], idx_non_zeros[1][i]] = elt
return t4
t1 = np.array([[1, 0, 0, 2],
[0, 0, 0, 0],
[0, 0, 0, 0],
[3, 0, 0, 4]])
t2 = get_nonzero(t1)
t3 = np.linalg.inv(t2)
t4 = restore_shape(t1, t3)
但正如评论中所建议的,
np.linalg.pinv(t1)
更加优雅和高效。您可以使用np.linalg.pinv(test)
@PaulPanzer谢谢,这就是我要找的,效果非常好!如果不是评论的话,我会接受这个答案。