重复NumPy数组而不复制数据?

时间:2011-04-06 09:20:57

标签: python numpy memory large-data

我想创建一个1D NumPy数组,该数组包含1000个背对背重复的另一个1D数组,而不会复制数据1000次。

有可能吗?

如果有帮助,我打算将两个数组都视为不可变。

5 个答案:

答案 0 :(得分:25)

你不能这样做; NumPy数组必须在每个维度上具有一致的步幅,而你的步幅大部分时间都需要单向运行,但有时会向后跳跃。

你可以得到的最接近的是一个1000行的二维数组,其中每一行都是你的第一个数组的视图,或者是flatiter object,它的行为类似于一维数组。 (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 object:

c = b.flat

答案 1 :(得分:6)

numpy 1.10中添加了

broadcast_to,这样可以轻松地重复一个数组。

复制已接受答案的样式:

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

答案 2 :(得分:1)

我不是100%确定你的意思是'不复制数据1000次'。如果您正在寻找一种从b一次性构建a的numpy方法(而不是循环),您可以使用:

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内存中的数组,只包含您想要的元素。

只要它们是不可变的(参见Immutable numpy array?),你需要分别切换每个标志,因为副本不保留标志设置。

答案 3 :(得分:0)

我并不认为这是最优雅的解决方案,因为你必须愚弄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])

答案 4 :(得分:0)

这会有效吗?

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