我可以在指定索引处获取numpy数组的视图吗?(来自“花式索引”的视图)
我需要一种方法,让“花式索引”(比如 y = x[[0, 5, 21]])返回的是一个视图,而不是一个副本。
我有一个数组,但我想能对这个数组的一个子集进行操作(这个子集是通过一组索引指定的),这样在这个子集上做的修改也能反映到大数组的正确位置上。如果我只想处理前10个元素,我可以直接用普通的切片 y = x[0:10]。这样很好,因为普通切片返回的是一个视图。问题是,如果我不想要0到10,而是想要一组任意的索引,该怎么做呢?
有没有办法做到这一点?
4 个回答
2
这里有一种可能的方法,可以模拟一个视图(就是一些语法上的小花样),通过使用一个“高级视图上下文”来避免在最后写出明确的复制语句。你需要注意的是,确保你的代码在这个上下文中不去修改索引数组。
import contextlib
@contextlib.contextmanager
def fancy_index_view(arr, inds):
# create copy from fancy inds
arr_copy = arr[inds]
# yield 'view' (copy)
yield arr_copy
# after context, save modified data
arr[inds] = arr_copy
现在,这段代码
import numpy as np
foo = np.random.random((22,2))
row_inds = [0,5,21]
barview = foo[row_inds]
barview[::] = 1
foo[row_inds] = barview
可以被替换为
import numpy as np
foo = np.random.random((22,2))
row_inds = [0,5,21]
with fancy_index_view(foo, row_inds) as barview:
barview[::] = 1
2
你可以直接这样做:
y = x[[0,1,4]]
func(y)
x[[0,1,4]] = y
我觉得用复杂的索引是无法获取视图的。其实你可能也不想这样,因为我觉得复杂索引的速度挺慢的,直接复制数据一次应该会更快。
16
我觉得这个问题没有简单的解决办法。我的理解是,所谓的“花式索引”总是会返回一个副本。对我来说,最好的办法就是先对 y
进行操作,然后再用相同的花式索引来修改 x
的值:
ii = [0, 5, 21]
y = x[ii]
<manipulate y>
x[ii] = y