【问题标题】:numpy 3d tensor by 2d arraynumpy 3d 张量乘 2d 数组
【发布时间】:2018-08-07 14:07:29
【问题描述】:

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

我有

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 并转置我的矩阵但没有运气。

【问题讨论】:

  • 不使用p可以解决吗?
  • @Divakar 当然,p 是我想解决它的方式,但我不太关心 p。我正在寻找某种方法来编码或分解src 并使其更小。此编码将应用于其他具有不同值但定位相同的src2。这就是我想到排列的原因。

标签: python numpy matrix sparse-matrix


【解决方案1】:

由于行优先排序,我们可以使用转置版本到 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]])

【讨论】:

  • 为每列处理任意数量的有效元素而无需在代码中指定它的奖励积分(当然,只要每列具有相同数量的有效元素)。
【解决方案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]])

【讨论】:

    【解决方案3】:

    你可以使用面具:

    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。

    【讨论】:

      【解决方案4】:

      这是一种方法:

      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]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-04
        • 1970-01-01
        • 2015-11-14
        • 2020-10-14
        • 1970-01-01
        相关资源
        最近更新 更多