Repeat NumPy array without replicating data?

北城以北 提交于 2019-11-27 20:34:30
Paul

You can't do this; a NumPy array must have a consistent stride along each dimension, while your strides would need to go one way most of the time but sometimes jump backwards.

The closest you can get is either a 1000-row 2D array where every row is a view of your first array, or a flatiter object, which behaves kind of like a 1D array. (flatiters support iteration and indexing, but you can't take views of them; all indexing makes a copy.)

Setup:

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

2D view:

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

flatiter object:

c = b.flat

broadcast_to was added in numpy 1.10, which allows you effectively repeat an array with a little less effort.

Copying the style of the accepted answer:

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

I'm not 100% sure what you mean by 'not replicating the data 1000 times'. If you are looking for a numpy method to build b from a in one fell swoop (rather than looping), you can use:

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

Otherwise, I would do something like:

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

b is not a view of a in this case because of the fancy indexing (it makes a copy), but at least it returns a numpy array and doesn't create the 1000*1000x1 array in memory and just contains the elements you want.

As far as them being immutable (see Immutable numpy array?), you would need to switch the flag for each separately since copies don't retain the flag setting.

I do not claim that this is the most elegant solution, because you have to fool numpy into creating an array of objects (see the line with the comment)

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

Would this work:

import numpy
a = numpy.array([1, 2, 3, 4])
b = numpy.ones((1000, a.shape[0]))
b *= a
b = b.flatten()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!