【问题标题】:Numpy matrix sum without looping没有循环的numpy矩阵和
【发布时间】:2018-04-23 12:04:57
【问题描述】:

尝试构建一个没有双 for 循环的 numpy 矩阵

如果我有一个矩阵:

x = [val, val, val]
    [val, val, val]
    [val, val, val]

我想用其他两行减去每一行的项目,同时外推到一个更大的矩阵并得到最终结果。每行减法(在本例中)是 3 个元素。 (不过我正在使用更大的矩阵)

new = [row 1 - 2,      0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
      [row 1 - 3,      0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
      [0.0, 0.0, 0.0,  row 2 - 1,     0.0, 0.0, 0.0]
      [0.0, 0.0, 0.0,  row 2 - 3,     0.0, 0.0, 0.0]
      [0.0, 0.0, 0.0,  0.0, 0.0, 0.0  row 3 - 1]
      [0.0, 0.0, 0.0,  0.0, 0.0, 0.0  row 3 - 2]

然后类似,但用列代替,除了项目是水平填充的,如果有意义的话(每个项目都是单个值而不是上面)

new = [col 1 - 2, 0.0, 0.0, col 1 - 2, 0.0, 0.0, col 1 - 2, 0.0, 0.0]
      [col 1 - 3, 0.0, 0.0, col 1 - 3, 0.0, 0.0, col 1 - 3, 0.0, 0.0]
      [0.0, col 2 - 1, 0.0, 0.0, col 2 - 1, 0.0, 0.0, col 2 - 1, 0.0]
      [0.0, col 2 - 3, 0.0, 0.0, col 2 - 3, 0.0, 0.0, col 2 - 3, 0.0]
      [0.0, 0.0, col 3 - 1, 0.0, 0.0, col 3 - 1, 0.0, 0.0, col 3 - 1]
      [0.0, 0.0, col 3 - 2, 0.0, 0.0, col 3 - 2, 0.0, 0.0, col 3 - 2]

如果有人有 numpy 的魔法来解决这个问题,我会失去它哈。

编辑:小矩阵的更好示例:

x = [[.5, 0.], 
     [.1, 1.2]]

变成

new = [[ 0.4, -1.2,  0.,   0. ],
       [ 0.,   0.,  -0.4,  1.2]]

对于列版本

y = [[.2, .9], 
     [.6, .1]]

变成

new = [[-0.7,  0.,   0.5,  0. ],
       [ 0.,   0.7,  0.,  -0.5]]

【问题讨论】:

  • 你能举一个有意义的实际例子吗?有了实际数字,所以很清楚发生了什么?我不确定我是否理解你编造的符号。
  • 确定我会使用 4 x 4 矩阵
  • 谢谢。什么都行。
  • 希望对您有所帮助,我看不到任何循环的方法,但计算需要很长时间,如果 numpy 能做点什么就太好了。
  • 我怀疑你的描述。可以发在这里吗?

标签: python numpy


【解决方案1】:

这里有一些疯狂的索引,我相信它可以满足您的要求:

>>> def magic(data):
...     n, m = data.shape
...     assert n==m
...     rows = np.zeros((n, n-1, n, n), data.dtype)
...     cols = np.zeros((n, n-1, n, n), data.dtype)
...     idx = np.argsort(np.identity(n), kind='mergesort', axis=1)
...     self = idx[:, -1] # should be just 0, 1, 2, 3, ...
...     other = idx[:, :-1]
...     rows[self, :, self, :] = data[:, None, :] - data[other[..., None], self]
...     cols[self, ..., self] = data.T[:, None, :] - data.T[other[..., None], self] 
...     return rows.reshape(-1, n*n), cols.reshape(-1, n*n)
... 
>>> magic(np.array([[.5,0], [.1,1.2]]))
(array([[ 0.4, -1.2,  0. ,  0. ],
       [ 0. ,  0. , -0.4,  1.2]]), array([[ 0.5,  0. , -1.1,  0. ],
       [ 0. , -0.5,  0. ,  1.1]]))
>>> magic(np.array([[.2,.9], [.6,.1]]))
(array([[-0.4,  0.8,  0. ,  0. ],
       [ 0. ,  0. ,  0.4, -0.8]]), array([[-0.7,  0. ,  0.5,  0. ],
       [ 0. ,  0.7,  0. , -0.5]]))

【讨论】:

  • 第一部分肯定有效,尝试调试第二部分的问题。不过,很棒的工作,老实说,我不确定这是否可能。 'self' 的使用一开始让我很反感,因为它是一个 python 关键字。
  • @MarkII 你能详细说明什么问题吗?在我看来,它在两个测试用例中都给出了您预期的结果。另外 - 很抱歉我很迂腐 - self 不是关键字,它只是按惯例使用。
  • 没关系,我是个白痴。我正在用转置版本覆盖我的测试矩阵。就像我说的那样晚了。这绝对是正确的答案。
  • @MarkII 不用担心,我自己有时也有点散漫。
  • 这再次令人难以置信,我肯定需要使用 numpy 变得更好。我有 99% 的把握没有机会。迫不及待地实施并看到计算时间的变化。
猜你喜欢
  • 1970-01-01
  • 2022-08-05
  • 2017-09-23
  • 1970-01-01
  • 2020-12-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多