Как транслировать 1d массив в массив ND в Python - PullRequest
0 голосов
/ 11 февраля 2019

Я что-то здесь упускаю.У меня есть 1-D массив, который я хочу транслировать в массив 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)

Ответы [ 4 ]

0 голосов
/ 11 февраля 2019

Вещание имеет два этапа:

  • развернуть размеры слева, чтобы соответствовать
  • развернуть все размеры размера 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) работает,и transpose может изменить это значение на (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]]])
0 голосов
/ 11 февраля 2019

Если вы хотите что-то подмножество трансляции, как вы упомянули, то вы можете нарезать массив.

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

Это дает требуемый результат, который вы хотели.

0 голосов
/ 11 февраля 2019

Решение

Вам необходимо иметь размер последнего измерения в качестве размера первого аргумента (массив 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
0 голосов
/ 11 февраля 2019

Когда вы транслируете на ND, новая форма должна соответствовать входным данным массива 1-D.Например, вы можете сделать:

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

или

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

Он не может транслировать 12 чисел в измерении длиной 2 из вашего примера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...