【发布时间】:2010-09-06 11:35:29
【问题描述】:
我在 NumPy 中有以下数组:
A = array([1, 2, 3])
如何获得以下矩阵(没有显式循环)?
B = [ 1 1 1
2 2 2
3 3 3 ]
C = [ 1 2 3
1 2 3
1 2 3 ]
谢谢!
【问题讨论】:
标签: python arrays numpy broadcast
我在 NumPy 中有以下数组:
A = array([1, 2, 3])
如何获得以下矩阵(没有显式循环)?
B = [ 1 1 1
2 2 2
3 3 3 ]
C = [ 1 2 3
1 2 3
1 2 3 ]
谢谢!
【问题讨论】:
标签: python arrays numpy broadcast
Edit2:OP 在 cmets 中询问如何计算
n(i, j) = l(i, i) + l(j, j) - 2 * l(i, j)
我可以想到两种方法。我喜欢这种方式,因为它很容易概括:
import numpy as np
l=np.arange(9).reshape(3,3)
print(l)
# [[0 1 2]
# [3 4 5]
# [6 7 8]]
这个想法是使用np.ogrid。这定义了两个 numpy 数组的列表,一个是形状 (3,1),一个是形状 (1,3):
grid=np.ogrid[0:3,0:3]
print(grid)
# [array([[0],
# [1],
# [2]]), array([[0, 1, 2]])]
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]]
但是,在这种特殊情况下,由于 l(i,i) 和 l(j,j) 只是 l 的对角线元素,您可以这样做:
d=np.diag(l)
print(d)
# [0 4 8]
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]]
Edit1:通常不需要形成B 或C。 Numpy 广播的目的是允许您使用A 代替B 或C。如果您向我们展示您打算如何使用 B 或 C,我们也许可以向您展示如何使用 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]])
或
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]])
来自恶作剧部门:
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]])
但请注意,这些是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])
【讨论】:
n(i, j) = l(i, i) + l(j, j) - 2 * l(i, j) 并在矩阵 N 中得到结果
非常古老的线程,但以防万一有人关心......
C,B = np.meshgrid(A,A)
【讨论】: