没有循环的Numpy矩阵和

时间:2018-04-23 02:55:46

标签: python numpy

尝试构建一个没有双循环的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]

然后类似但是用列代替,除了项目是水平填充,如果这是有道理的(每个项目是单个值vs上面)

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]

如果某人有这种笨拙的魔法,我会失去它哈哈。

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

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

1 个答案:

答案 0 :(得分:3)

这是一些索引的疯狂,我相信你所要求的是:

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