Numpy 广播数组

发布于 2024-09-17 08:16:19 字数 211 浏览 4 评论 0原文

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

谢谢!

I have the following array in NumPy:

A = array([1, 2, 3])

How can I obtain the following matrices (without an explicit loop)?

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

C = [ 1 2 3
      1 2 3
      1 2 3 ]

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眼眸印温柔 2024-09-24 08:16:19

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

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] 可以用作索引 的代理我,和
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:通常您不需要形成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]])

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

Edit2: The OP asks in the comments how to compute

n(i, j) = l(i, i) + l(j, j) - 2 * l(i, j)

I can think of two ways. I like this way because it generalizes easily:

import numpy as np

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

The idea is to use np.ogrid. This defines a list of two numpy arrays, one of shape (3,1) and one of shape (1,3):

grid=np.ogrid[0:3,0:3]
print(grid)
# [array([[0],
#        [1],
#        [2]]), array([[0, 1, 2]])]

grid[0] can be used as a proxy for the index i, and
grid[1] can be used as a proxy for the index j.

So everywhere in the expression l(i, i) + l(j, j) - 2 * l(i, j), you simply replace i-->grid[0], and j-->grid[1], and numpy broadcasting takes care of the rest:

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

However, in this particular case, since l(i,i) and l(j,j) are just the diagonal elements of l, you could do this instead:

d=np.diag(l)
print(d)
# [0 4 8]

d[np.newaxis,:] pumps up the shape of d to (1,3), and
d[:,np.newaxis] pumps up the shape of d to (3,1).

Numpy broadcasting pumps up d[np.newaxis,:] and d[:,np.newaxis] to shape (3,3), copying values as appropriate.

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

Edit1: Usually you do not need to form B or C. The purpose of Numpy broadcasting is to allow you to use A in place of B or C. If you show us how you plan to use B or C, we might be able to show you how to do the same with A and numpy broadcasting.


(Original answer):

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

or

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

From the dirty tricks department:

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

But note that these are views of A, not copies (as were the solutions above). Changing B, alters 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])

不知所踪 2024-09-24 08:16:19

非常旧的线程,但以防万一有人关心......

C,B = np.meshgrid(A,A)

Very old thread but just in case someone cares...

C,B = np.meshgrid(A,A)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文