Здесь происходит ряд вещей, и было бы проще работать с массивом, содержащим небольшое количество значений флагов, для выявления проблем. Вот пример, с которым легко работать:
arr = np.array([[1, 2, 1, 2], [3, 4, 3, 4]]) # n = 2, d = 4
Давайте посмотрим, что делает broadcast_to
:
>>> A.reshape(n, 1, d)
array([[[1, 2, 1, 2]],
[[3, 4, 3, 4]]])
>>> arr.broadcast_to(_, (n, d - 1, d))
array([[[1, 2, 1, 2],
[1, 2, 1, 2],
[1, 2, 1, 2]],
[[3, 4, 3, 4],
[3, 4, 3, 4],
[3, 4, 3, 4]]])
Вы можете получить функционально аналогичные массивы с tile
, stack
и concatenate
. Основное отличие состоит в том, что broadcast_to
делает , а не копирует данные в новом измерении. Вместо этого он корректирует шаг так, чтобы массив имел правильный размер (что приводит к неожиданному поведению, если вы неосторожны, например, при записи в буфер):
np.tile(arr.reshape(n, 1, d), (1, d - 1, 1))
np.stack([arr] * (d - 1), axis=1)
np.concatenate([arr.reshape(n, 1, d)] * (d - 1), axis=1)
Теперь давайте взглянем на repeat
:
>>> np.repeat(arr, d - 1)
array([1, 1, 1, 2, 2, 2, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 3, 3, 3, 4, 4, 4])
Это плоский массив, каждый элемент которого повторяется d - 1
раз. Очевидно, что изменение формы здесь не будет таким же, как у широковещательной / плиточной версии:
>>> _.reshape(n, d - 1, d)
array([[[1, 1, 1, 2],
[2, 2, 1, 1],
[1, 2, 2, 2]],
[[3, 3, 3, 4],
[4, 4, 3, 3],
[3, 4, 4, 4]]])
Очевидно, что поэлементное повторение не идентично трансляции. Однако, если бы вы использовали правильное ключевое слово axis
, вы могли бы получить правильный результат:
>>> np.repeat(arr.reshape(n, 1, d), d - 1, axis=1)
array([[[1, 2, 1, 2],
[1, 2, 1, 2],
[1, 2, 1, 2]],
[[3, 4, 3, 4],
[3, 4, 3, 4],
[3, 4, 3, 4]]])
Если бы вы хотели go другим способом, и данные были бы короче строк, вы можете просто заново интерпретировать размеры, используя комбинацию transpose
и reshape
:
>>> np.broadcast_to(arr.reshape(n, 1, d), (n, d - 1, d)).transpose([0, 2, 1]).reshape(n, d - 1, d)
array([[[1, 1, 1, 2],
[2, 2, 1, 1],
[1, 2, 2, 2]],
[[3, 3, 3, 4],
[4, 4, 3, 3],
[3, 4, 4, 4]]])
Вот пошаговое руководство по преобразованию:
>>> arr.reshape(n, 1, d)
array([[[1, 2, 1, 2]],
[[3, 4, 3, 4]]])
>>> np.broadcast_to(_, (n, d - 1, d))
array([[[1, 2, 1, 2],
[1, 2, 1, 2],
[1, 2, 1, 2]],
[[3, 4, 3, 4],
[3, 4, 3, 4],
[3, 4, 3, 4]]])
>>> _.transpose(0, 2, 1)
array([[[1, 1, 1],
[2, 2, 2],
[1, 1, 1],
[2, 2, 2]],
[[3, 3, 3],
[4, 4, 4],
[3, 3, 3],
[4, 4, 4]]])
>>> _.reshape(n, d - 1, d)
array([[[1, 1, 1, 2],
[2, 2, 1, 1],
[1, 2, 2, 2]],
[[3, 3, 3, 4],
[4, 4, 3, 3],
[3, 4, 4, 4]]])