Повторите массив NumPy без репликации данных? - PullRequest
20 голосов
/ 06 апреля 2011

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

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

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

Ответы [ 5 ]

25 голосов
/ 06 апреля 2011

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

Настройка:

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

2D просмотр:

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

плоский объект:

c = b.flat
6 голосов
/ 14 июня 2016

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

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

import numpy as np
arr = np.arange(10)
repeated = np.broadcast_to(arr, (1000, arr.size))
1 голос
/ 06 апреля 2011

Я не на 100% уверен, что вы имеете в виду, когда не повторяете данные 1000 раз.Если вы ищете простой способ построения 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 из-за причудливого индексирования (оно создает копию), но, по крайней мере, возвращает пустой массив и не создает 1000 * 1000x1массив в памяти и просто содержит элементы, которые вы хотите.

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

0 голосов
/ 06 апреля 2011

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

import numpy
a = numpy.array([1, 2, 3, 4])
b = numpy.ones((1000, a.shape[0]))
b *= a
b = b.flatten()
0 голосов
/ 06 апреля 2011

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

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