如何对一组特定的numpy数组行进行就地处理

时间:2015-10-27 21:04:24

标签: python numpy

在以下示例中,我想将一组特定行修改为一个组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.]]

1 个答案:

答案 0 :(得分:1)

在NumPy中,"basic slices",例如x[2, :],会返回视图。

所谓的"advanced indexing", 例如x[(0,1,3), :],返回数组的副本。

在引擎盖下,NumPy数组将值存储在连续的内存块中 根据{{​​1}},dtypeshape访问值。价值 根据步幅,它们本身可能在该内存块中是不连续的,但是每个数组都引用来自单个内存块的值。

高级索引允许您从此内存块中选择任意行。 通常,无法使用原始数据指定结果数组 记忆块,只是一个dtype,形状和步幅。因此,结果数组的值必须是 复制到一个新数组。这就是高级索引始终返回副本的原因。

修改数组副本(如预期的那样)不会影响原始数组。这就是将strides传递给x[(0, 1, 3), :]不会影响inplace_place的原因。

但是,分配 - 即使左侧使用高级索引 - 确实会影响原始数组。例如

x

会影响x[(0, 1, 3), :] = C*N 。因此,您可以通过将行传递到x并在inplace_process执行分配来修复代码:

a[rows, :]