25

我想创建一个一维 NumPy 数组,该数组由另一个一维数组的 1000 次背靠背重复组成,而不复制数据 1000 次。

是否可以?

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

4

5 回答 5

28

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

您可以获得的最接近的是 1000 行 2D 数组,其中每一行都是您的第一个数组的视图,或者是一个flatiterobject,它的行为类似于 1D 数组。(flatiters 支持迭代和索引,但您不能查看它们;所有索引都会复制。)

设置:

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

二维视图:

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

扁平化对象:

c = b.flat
于 2011-04-06T14:37:32.340 回答
16

broadcast_to是在 numpy 1.10 中添加的,它允许您以更少的努力有效地重复一个数组。

复制已接受答案的样式:

import numpy as np
arr = np.arange(10)
repeated = np.broadcast_to(arr, (1000, arr.size))
于 2016-06-14T18:30:39.587 回答
2

我不是 100% 确定您所说的“不复制数据 1000 次”是什么意思。如果您正在寻找一种一举(而不是循环)构建的 numpy 方法,您可以使用ba

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?),您需要分别为每个切换标志,因为副本不保留标志设置。

于 2011-04-06T12:46:51.523 回答
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])
于 2011-04-06T13:02:45.850 回答
0

这会起作用吗:

import numpy
a = numpy.array([1, 2, 3, 4])
b = numpy.ones((1000, a.shape[0]))
b *= a
b = b.flatten()
于 2011-04-06T14:55:37.280 回答