如何在不复制数据的情况下重复NumPy数组?

25 投票
5 回答
11019 浏览
提问于 2025-04-16 15:11

我想创建一个一维的NumPy数组,这个数组由另一个一维数组重复1000次组成,但我不想把数据复制1000遍。

这样做可以吗?

如果有帮助的话,我打算把这两个数组都当作不可改变的。

5 个回答

2

我不太确定你说的“数据不重复1000次”是什么意思。如果你想用numpy的方法一次性从a生成b(而不是通过循环),你可以使用:

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数组?),你需要为每个单独切换标志,因为副本不会保留标志设置。

19

broadcast_to 是在 numpy 1.10 版本中新增的功能,它可以让你更轻松地重复一个数组。

模仿被接受答案的风格:

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

你不能这样做;NumPy数组在每个维度上必须保持一致的步幅,而你的步幅大部分时间需要朝一个方向,但有时又要跳回去。

你能做到的最接近的方式是创建一个1000行的二维数组,每一行都是你第一个数组的一个视图,或者使用一个flatiter对象,它的表现有点像一维数组。(flatiter支持迭代和索引,但你不能对它们进行视图操作;所有的索引操作都会生成一个副本。)

设置:

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

二维视图:

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

flatiter对象:

c = b.flat

撰写回答