Numpy广播阵列

yas*_*sin 2 python arrays numpy broadcast

我在NumPy中有以下数组:

A = array([1, 2, 3])
Run Code Online (Sandbox Code Playgroud)

如何获得以下矩阵(没有显式循环)?

B = [ 1 1 1
      2 2 2
      3 3 3 ]

C = [ 1 2 3
      1 2 3
      1 2 3 ]
Run Code Online (Sandbox Code Playgroud)

谢谢!

unu*_*tbu 7

Edit2:OP在评论中询问如何计算

n(i, j) = l(i, i) + l(j, j) - 2 * l(i, j)
Run Code Online (Sandbox Code Playgroud)

我可以想到两种方式.我喜欢这种方式,因为它很容易概括:

import numpy as np

l=np.arange(9).reshape(3,3)
print(l)
# [[0 1 2]
#  [3 4 5]
#  [6 7 8]]
Run Code Online (Sandbox Code Playgroud)

这个想法是用的np.ogrid.这定义了两个numpy数组的列表,一个是shape(3,1),另一个是shape(1,3):

grid=np.ogrid[0:3,0:3]
print(grid)
# [array([[0],
#        [1],
#        [2]]), array([[0, 1, 2]])]
Run Code Online (Sandbox Code Playgroud)

grid[0]可以用作索引的代理i,并 grid[1]可以用作索引的代理j.

所以在表达式的任何地方l(i, i) + l(j, j) - 2 * l(i, j),你只需要替换i- > grid[0]j- > grid[1],并且numpy广播会处理剩下的事情:

n=l[grid[0],grid[0]] + l[grid[1],grid[1]] + 2*l
print(n)
# [[ 0  6 12]
#  [10 16 22]
#  [20 26 32]]
Run Code Online (Sandbox Code Playgroud)

但是,在这种特殊情况下,由于l(i,i)而且l(j,j)只是对角元素l,你可以这样做:

d=np.diag(l)
print(d)
# [0 4 8]
Run Code Online (Sandbox Code Playgroud)

d[np.newaxis,:]泵送形状d为(1,3),并 d[:,np.newaxis]形成d(3,1)的形状.

Numpy广播泵出d[np.newaxis,:]d[:,np.newaxis]成型(3,3),酌情复制值.

n=d[np.newaxis,:] + d[:,np.newaxis] + 2*l
print(n)
# [[ 0  6 12]
#  [10 16 22]
#  [20 26 32]]
Run Code Online (Sandbox Code Playgroud)

编辑1:通常你不需要形成BC.Numpy广播的目的是让你用来A代替BC.如果您向我们展示您打算如何使用BC,我们可能会告诉您如何使用A和numpy广播做同样的事情.


(原始答案):

In [11]: B=A.repeat(3).reshape(3,3)

In [12]: B
Out[12]: 
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])

In [13]: C=B.T

In [14]: C
Out[14]: 
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])
Run Code Online (Sandbox Code Playgroud)

要么

In [25]: C=np.tile(A,(3,1))

In [26]: C
Out[26]: 
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])

In [27]: B=C.T

In [28]: B
Out[28]: 
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])
Run Code Online (Sandbox Code Playgroud)

来自肮脏的技巧部门:

In [57]: np.lib.stride_tricks.as_strided(A,shape=(3,3),strides=(4,0))
Out[57]: 
array([[1, 1, 1],
       [2, 2, 2],
       [3, 3, 3]])

In [58]: np.lib.stride_tricks.as_strided(A,shape=(3,3),strides=(0,4))
Out[58]: 
array([[1, 2, 3],
       [1, 2, 3],
       [1, 2, 3]])
Run Code Online (Sandbox Code Playgroud)

但需要注意的是,这些都是观点A,不是复印件(因为是上面的解决方案).改变B,改变A:

In [59]: B=np.lib.stride_tricks.as_strided(A,shape=(3,3),strides=(4,0))

In [60]: B[0,0]=100

In [61]: A
Out[61]: array([100,   2,   3])
Run Code Online (Sandbox Code Playgroud)