在以下示例中,我想将一组特定行修改为一个组in-place
。第一次调用 inplace_process 似乎会导致传递数组的副本,而第二次调用 inplace_process 会直接修改 x 变量。< / p>
我实际使用案例中数组的大小太大,无法创建副本,我正在调用项目外部的代码。
import numpy as np
def inplace_process(a, C, N):
a.shape = (C, N)
a[:, :] = float(C*N)
C = 4
N = 128
x = np.zeros((C, N))
# process a specific set of rows
inplace_process(x[(0, 1, 3), :], 3, N)
# independently process an inner row
inplace_process(x[2, :], 1, N)
print '-----------------------------------------------------'
print ' We want C*N and not zeros'
print x
输出:
[[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0.]
[ 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128. 128.
128. 128. 128. 128. 128. 128. 128. 128.]
[ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.
0. 0. 0. 0. 0. 0. 0. 0.]]
答案 0 :(得分:1)
在NumPy中,"basic slices",例如x[2, :]
,会返回视图。
所谓的"advanced
indexing",
例如x[(0,1,3), :]
,返回数组的副本。
在引擎盖下,NumPy数组将值存储在连续的内存块中
根据{{1}},dtype
和shape
访问值。价值
根据步幅,它们本身可能在该内存块中是不连续的,但是每个数组都引用来自单个内存块的值。
高级索引允许您从此内存块中选择任意行。 通常,无法使用原始数据指定结果数组 记忆块,只是一个dtype,形状和步幅。因此,结果数组的值必须是 复制到一个新数组。这就是高级索引始终返回副本的原因。
修改数组副本(如预期的那样)不会影响原始数组。这就是将strides
传递给x[(0, 1, 3), :]
不会影响inplace_place
的原因。
但是,分配 - 即使左侧使用高级索引 - 确实会影响原始数组。例如
x
会影响x[(0, 1, 3), :] = C*N
。因此,您可以通过将行传递到x
并在inplace_process
执行分配来修复代码:
a[rows, :]