简体   繁体   English

如何在 Python 中将一维数组广播到 ND 数组

[英]How to broadcast a 1d array to an N-D array in Python

I'm missing something here.我在这里遗漏了一些东西。 I have a 1-D array that I want to broadcast to an ND array, and it's not working:我有一个一维数组,我想广播到一个 ND 数组,但它不起作用:

>>> import numpy as np
>>> np.broadcast_to(np.arange(12),(12,2,2))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "c:\app\python\anaconda\2\lib\site-packages\numpy\lib\stride_tricks.py", line 173, in broadcast_to
    return _broadcast_to(array, shape, subok=subok, readonly=True)
  File "c:\app\python\anaconda\2\lib\site-packages\numpy\lib\stride_tricks.py", line 128, in _broadcast_to
    op_flags=[op_flag], itershape=shape, order='C').itviews[0]
ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (12,) and requested shape (12,2,2)

Solution解决方案

You need to have size of last dimension as a size of first argument(arange array).您需要将最后一个维度的大小作为第一个参数(arange 数组)的大小。 This works.这有效。 Just put 12 at the end and transpose只需将 12 放在最后并转置

import numpy as np
np.broadcast_to(np.arange(12),(2,2,12)).T # so it fits exactly your question, transpose

>>> np.broadcast_to(np.arange(12),(2,2,12)).T.shape
(12, 2, 2)

NOTE笔记

Looking at documentations, it seems you really need to have corresponding shapes at both - array & desired shape.查看文档,似乎您确实需要在两者上都有相应的形状 - 数组和所需的形状。 If you have如果你有

np.arange(X)

then you can have any desired shape as long as the last dimension has shape X那么你可以有任何想要的形状,只要最后一个维度的形状是 X

np.broadcast_to(np.arange(X),(ANY,ANY,ANY,ANY,ANY,X))

you can test it with this funny example你可以用这个有趣的例子来测试它

X = 10
np.broadcast_to(np.arange(X),[i for i in range(X+1)]).shape

EDIT:编辑:

In relation to @Divakar's comment to OP (adding extra dimensions), it looks there are two possible ways with same results关于@Divakar对 OP评论(添加额外维度),看起来有两种可能的方法具有相同的结果

solution1 = np.broadcast_to(np.arange(12)[:,None,None], (12,2,2)) # Divakar's
solution2 = np.broadcast_to(np.arange(12),(12,2,2)[::-1]).T # without extra dimensions, using Transpose

>>> np.all(solution1 == solution2)
True

Broadcasting has two steps:广播有两个步骤:

  • expand dimensions on the left to match展开左侧的尺寸以匹配
  • expand all size 1 dimensions to match展开所有尺寸 1 的尺寸以匹配

With a size (12,) array, the first step can produce (1,1,12), but not (12,1,1).对于大小为 (12,) 的数组,第一步可以生成 (1,1,12),但不能生成 (12,1,1)。 The second step could then expand to (2,2,12).第二步可以扩展到(2,2,12)。 But you want (12,2,2).但是你想要 (12,2,2)。

So you have to explicitly add the trailing dimensions所以你必须明确添加尾随尺寸

In [773]: np.broadcast_to(np.arange(12)[:,None,None], (12,2,2)).shape
Out[773]: (12, 2, 2)

In [775]: np.broadcast_to(np.arange(3)[:,None,None], (3,2,2))
Out[775]: 
array([[[0, 0],
        [0, 0]],

       [[1, 1],
        [1, 1]],

       [[2, 2],
        [2, 2]]])

So by these rules broadcasting to (2,2,12) works, and transpose can change that to (12,2,2)因此,通过这些规则广播到 (2,2,12) 起作用,并且转置可以将其更改为 (12,2,2)

Broadcasting to (12,12,12) is equivalent to expanding (1,1,12).广播到 (12,12,12) 相当于扩展 (1,1,12)。 The arange is the last dimension, not the first. arange是最后一个维度,而不是第一个维度。 We don't want to slice that last dimension我们不想切割最后一个维度

In [777]: np.broadcast_to(np.arange(3),(3,3,3))[:,:2,:2]
Out[777]: 
array([[[0, 1],
        [0, 1]],

       [[0, 1],
        [0, 1]],

       [[0, 1],
        [0, 1]]])

When you broadcast to ND, the new shape has to match the input of the 1-D array.当您广播到 ND 时,新形状必须与一维数组的输入相匹配。 For example, you could do:例如,你可以这样做:

np.broadcast_to(np.arange(12),(12,12))

or或者

np.broadcast_to(np.arange(12),(12,12,12))

It can't broadcast 12 numbers into a dimension with length 2, from your example.从您的示例中,它无法将 12 个数字广播到长度为 2 的维度中。

If you want something subset of the broadcast as you mentioned then you can slice the array.如果你想要一些你提到的广播的子集,那么你可以对数组进行切片。

arr = np.broadcast_to(np.arange(12),(12,12,12))
arr = arr[:,:2,:2]

This gives the required result you wanted.这给出了您想要的所需结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM