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

时间:2019-02-11 16:50:04

标签: python numpy numpy-broadcasting

我在这里丢失了一些东西。我有一个要广播到N-D阵列的一维阵列,但它不起作用:

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

4 个答案:

答案 0 :(得分:2)

解决方案

您需要具有最后一个尺寸的大小作为第一个参数(arange数组)的大小。 这可行。只需将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)

注意

查看文档,似乎您确实确实需要同时具有相应的形状-数组和所需形状。如果有

np.arange(X)

然后,您可以具有任何所需的形状,只要最后一个尺寸的形状为X

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

您可以通过这个有趣的示例进行测试

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

编辑:

相对于 @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

答案 1 :(得分:1)

广播有两个步骤:

  • 在左侧扩展尺寸以匹配
  • 展开所有尺寸为1的尺寸以匹配

使用大小为(12,)的数组,第一步可以生成(1,1,12),但不能生成(12,1,1)。然后第二步可以扩展到(2,2,12)。但是你想要(12,2,2)。

因此您必须明确添加尾随尺寸

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

因此,通过这些规则,广播到(2,2,12)是有效的,转置可以将其更改为(12,2,2)

广播到(12,12,12)相当于扩展(1,1,12)。 arange是最后一个维度,而不是第一个维度。我们不想切片最后一个维度

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

答案 2 :(得分:-1)

当您广播到N-D时,新形状必须与1-D阵列的输入匹配。例如,您可以这样做:

javac

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

根据您的示例,它无法将12个数字广播到长度为2的维度中。

答案 3 :(得分:-1)

如果您想要广播中提到的某些子集,则可以对数组进行切片。

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

这将提供所需的所需结果。