Существует ли `np.repeat`, который действует на существующий массив? - PullRequest
0 голосов
/ 09 января 2019

У меня есть большой массив NumPy, который я хочу заполнить новыми данными на каждой итерации цикла. Массив заполняется данными, повторенными вдоль оси 0, например:

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

Я знаю, как создавать этот массив с нуля в каждой итерации:

x = np.repeat([[1, 5]], 4, axis=0)

Однако я не хочу каждый раз создавать новый массив, потому что это очень большой массив (намного больше, чем 4x2). Вместо этого я хочу заранее создать массив, используя приведенный выше код, а затем просто заполнять массив новыми данными на каждой итерации.

Но np.repeat() возвращает новый массив, а не воздействует на существующий массив. Есть ли эквивалент np.repeat() для заполнения существующего массива?

1 Ответ

0 голосов
/ 10 января 2019

Как мы отмечали в комментариях, вы можете использовать широковещательное назначение, чтобы заполнить ваш 2d массив подобным массиву 1d соответствующего размера:

x[...] = [1, 5]

Если по какой-либо причине ваш большой массив всегда содержит одинаковые элементы в каждой строке (т. Е. Вы не будете изменять эти предустановленные значения позже), вы почти наверняка сможете использовать широковещательную передачу в более поздних частях кода и просто работать с начальным x например

x = np.array([[1, 5]])

Этот массив имеет форму (1, 2), которая совместима с широковещательной передачей с другими массивами формы (4, 2), которые могут иметься в приведенном выше примере.

Если вам всегда нужны одни и те же значения в каждой строке и , по какой-то причине вы не можете использовать широковещание (оба случая крайне маловероятны), вы можете использовать broadcast_to для создания массива с явным 2D фигура без копирования памяти:

x_bc = np.broadcast_to([1, 5], (4, 2)) # broadcast 1d [1, 5] to shape (4, 2)

Это может сработать, потому что оно имеет правильную форму с двумя уникальными элементами в памяти:

>>> x_bc
array([[1, 5],
       [1, 5],
       [1, 5],
       [1, 5]])

>>> x_bc.strides
(0, 8)

Однако вы не можете изменить его, потому что это только для чтения:

>>> x_bc[0, :] = [2, 4]
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-35-ae12ecfe3c5e> in <module>
----> 1 x_bc[0, :] = [2, 4]

ValueError: assignment destination is read-only

Таким образом, если вам нужны только одинаковые значения в каждой строке и , вы не можете использовать широковещательную передачу и , если вы хотите изменить эти строки позже, вы можете использовать Уловки , чтобы отобразить те же 1d данные в 2d массив:

>>> x_in = np.array([1, 5])
... x_strided = np.lib.stride_tricks.as_strided(x_in, shape=(4,) + x_in.shape,
...                                             strides=(0,) + x_in.strides[-1:])

>>> x_strided
array([[1, 5],
       [1, 5],
       [1, 5],
       [1, 5]])

>>> x_strided[0, :] = [2, 4]

>>> x_strided
array([[2, 4],
       [2, 4],
       [2, 4],
       [2, 4]])

Что дает вам двумерный массив фиксированной формы, который всегда содержит одну уникальную строку, а мутирование любой из строк приводит к мутированию остальных (поскольку базовые данные соответствуют только одной строке). Обращайтесь с этим осторожно, потому что если вы хотите иметь два разных ряда, вам придется заняться чем-то другим.

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