Подтвердить что ты не робот

Повторить массив NumPy без репликации данных?

Я хотел бы создать массив 1D NumPy, который будет состоять из 1000 повторных повторений другого 1D-массива без повторения данных 1000 раз.

Возможно ли это?

Если это помогает, я намерен рассматривать оба массива как неизменные.

4b9b3361

Ответ 1

Вы не можете этого сделать; массив NumPy должен иметь согласованный шаг вдоль каждого измерения, в то время как ваши шаги должны будут идти в одну сторону большую часть времени, но иногда перепрыгивать назад.

Ближе всего вы можете получить либо массив из 1000 строк 2D, где каждая строка является представлением вашего первого массива, либо flatiter object, который ведет себя как 1D-массив. (flatiters поддерживают итерацию и индексирование, но вы не можете просматривать их, все индексирование делает копию.)

Настройка:

import numpy as np
a = np.arange(10)

2D-просмотр:

b = np.lib.stride_tricks.as_strided(a, (1000, a.size), (0, a.itemsize))

объект flatiter:

c = b.flat

Ответ 2

broadcast_to было добавлено в numpy 1.10, что позволяет эффективно повторять массив с меньшими усилиями.

Копирование стиля принятого ответа:

import numpy as np
arr = np.arange(10)
repeated = np.broadcast_to(arr, (1000, arr.size))

Ответ 3

Я не уверен на 100%, что вы подразумеваете под "не тиражированием данных 1000 раз". Если вы ищете метод numpy для создания b из a одним махом (а не с циклом), вы можете использовать:

a = np.arange(1000)
b = np.tile(a,1000)

В противном случае я бы сделал что-то вроде:

a = np.arange(1000)
ii = [700,2000,10000] # The indices you want of the tiled array
b = a[np.mod(ii,a.size)]

b не является видом a в этом случае из-за фантазии индексации (он делает копию), но по крайней мере он возвращает массив numpy и не создает массив 1000 * 1000x1 в памяти и просто содержит нужные элементы.

Насколько они являются неизменяемыми (см. Неизменяемый массив numpy?), вам нужно будет переключать флаг для каждого отдельно, так как копии не сохраняют установку флага.

Ответ 4

Я не утверждаю, что это самое элегантное решение, потому что вам нужно обмануть numpy в создании массива объектов (см. строку с комментарием)

from numpy import array

n = 3

a = array([1,2])
a.setflags(write=False)
t = [a]*n + [array([1])] # Append spurious array that is not len(a)
r = array(t,dtype=object)
r.setflags(write=False)

assert id(a) == id(t[1]) == id(r[1])

Ответ 5

Будет ли это работать:

import numpy
a = numpy.array([1, 2, 3, 4])
b = numpy.ones((1000, a.shape[0]))
b *= a
b = b.flatten()