numpy 3d张量乘2d数组

时间:2018-08-07 14:07:30

标签: python numpy matrix sparse-matrix

我有一个稀疏矩阵。我知道每个列都有两个非零值,所以我想使用定义为置换矩阵列表的张量压缩(除去零)。

我有

src = np.array([[2, 9, 0, 2, 4],
                [0, 1, 8, 8, 0],
                [1, 0, 3, 0, 0],
                [0, 0, 0, 0, 7]])

我想要

trg = np.array([[2, 9, 8, 2, 4],
                [1, 1, 3, 8, 7]])

是相同的矩阵,但没有零。

我已经对选择非零值的张量进行了硬编码

p = np.array([
    [[1,0,0,0],[0,0,1,0]],
    [[1,0,0,0],[0,1,0,0]],
    [[0,1,0,0],[0,0,1,0]],
    [[1,0,0,0],[0,1,0,0]],
    [[1,0,0,0],[0,0,0,1]]
])

我可以遍历psrc来获得trg

>>> for i in range(len(p)):
>>>    print(p[i] @ src[:,i])

[2 1]
[9 1]
[8 3]
[2 8]
[4 7]

如何以这种numpy方式(即无循环)执行此操作?我尝试过tensordot,并在没有运气的情况下对矩阵进行了转置。

4 个答案:

答案 0 :(得分:2)

由于行的主要顺序,我们可以使用转置后的版本index带有非零掩码的数组,然后重塑-

out = src.T[src.T!=0].reshape(src.shape[1],-1).T

样品运行-

In [19]: src
Out[19]: 
array([[2, 9, 0, 2, 4],
       [0, 1, 8, 8, 0],
       [1, 0, 3, 0, 0],
       [0, 0, 0, 0, 7]])

In [20]: src.T[src.T!=0].reshape(src.shape[1],-1).T
Out[20]: 
array([[2, 9, 8, 2, 4],
       [1, 1, 3, 8, 7]])

答案 1 :(得分:2)

使用np.where的解决方案:

src[np.where(src.T)[::-1]].reshape(2, -1, order='F')

会发生这种情况:

  • np.where使用转置给出非零元素的索引,这样就可以正确地对它们进行排序,而无需采取其他措施,
  • [::-1]反转顺序,因为由于转置,行和列索引被交换,
  • 应用advanced indexing获取元素,
  • 最后,重塑。

输出:

array([[2, 9, 8, 2, 4],
       [1, 1, 3, 8, 7]])

答案 2 :(得分:1)

您可以使用口罩:

mask = src != 0
src[mask] #array without the zeroes but 1d
n_cols = src.shape[1]
tgt = src[mask].reshape(-1,n_cols)

此方法需要将1d数组重塑为2d,我决定保留相同的列数,但在某些情况下,您的数组可能对2d不太满意。

答案 3 :(得分:1)

这是一种方法:

import numpy as np

src = np.array([[2, 9, 0, 2, 4],
                [0, 1, 8, 8, 0],
                [1, 0, 3, 0, 0],
                [0, 0, 0, 0, 7]])
# Masked indices of non-zero positions
idx = np.arange(len(src))[:, np.newaxis] * (src != 0)
# Sort to and pick valid indices at the end
idx = np.sort(idx, axis=0)[-2:]
# Get values
trg = src[idx, np.arange(src.shape[1])]
print(trg)

输出:

[[2 9 8 2 4]
 [1 1 3 8 7]]