使用列表索引numpy数组时避免复制

6 投票
1 回答
3099 浏览
提问于 2025-04-18 07:21

有没有简单的方法可以用列表或其他集合来索引数组,这样就不会复制数据,而只是获取数组的一个视图?请不要根据下面的代码片段来回答这个问题——我用来索引元素的列表不总是很短(比如说可能有几千个元素,而不是只有4个),而且这个列表是通过某个算法生成的,所以里面的数字不一定是有序的等等。

举个例子,在下面的代码中,第一和第二种情况都选择了第1、2和3列,但只有在第一种情况下返回的是数据的一个视图:

>>> a[:,1:4]
>>> b = a[:,1:4]
>>> b.base is a
True
>>> c = a[:,[1,3,2]]
>>> c.base is a
False

1 个回答

10

所谓的“花式索引”(就是用一个索引列表来访问数组中的元素)总是会生成一个副本,因为numpy无法把它转化为同一数据的新视图,虽然这个视图的步幅和形状不同,并且是从某个特定元素开始的。

从底层来看,numpy数组其实是指向数组第一个元素在内存中的指针,还有数据类型、形状以及一些信息,告诉你在内存中要移动多远才能到达每个维度(比如下一行、下一列等等),还有一些标志。对已有内存的视图只是指向数组中的某个元素,并调整步幅和形状。而花式索引通常是随机访问这些已有内存中的数据,你无法强行把这些数据变成所需的形式,所以必须创建一个副本。

撰写回答