[英]How to do in-place processing of a specific set of numpy array rows
在以下示例中,我要in-place
一组特定的行修改为一组。 第一次调用inplace_process似乎导致传递了数组的副本,而第二次调用inplace_process则直接修改了x变量。
在我的实际用例中,数组的大小太大,无法创建副本,而我正在调用项目外部的代码。
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.]]
在NumPy中, “基本切片” (例如x[2, :]
,: x[2, :]
)返回视图。
所谓的“高级索引” ,例如x[(0,1,3), :]
,返回数组的副本。
引擎盖下,NumPy的阵列存储值在存储器的连续块和访问基于所述值dtype
, shape
和strides
。 根据跨步,值本身在该内存块中可能是不连续的,但是每个数组都引用单个内存块中的值。
高级索引允许您从该内存块中选择任意行。 通常,无法使用原始的内存块来指定结果数组,而只能使用dtype,shape和stride。 因此,必须将结果数组的值复制到新数组中。 这就是为什么高级索引总是返回副本的原因。
修改阵列副本(如人们所料)不会影响原始阵列。 这就是为什么将x[(0, 1, 3), :]
inplace_place
x[(0, 1, 3), :]
inplace_place
x[(0, 1, 3), :]
传递给inplace_place
不会影响x
。
但是,赋值(即使左侧使用高级索引)也会影响原始数组。 例如
x[(0, 1, 3), :] = C*N
会影响x
。 因此,您可以通过将行传递到inplace_process
并执行对a[rows, :]
inplace_process
a[rows, :]
的赋值来修复代码:
import numpy as np
def inplace_process(a, rows, C, N):
a[rows, :] = 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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.