2015-10-27 2 views
0

В следующем примере я хотел бы изменить определенный набор строк как группу, in-place. Первый вызов inplace_process, по-видимому, приводит к копированию передаваемого массива, тогда как второй вызов inplace_process изменяет непосредственно переменную x.Как сделать обработку на месте определенного набора строк массива numpy

Размер массива в моем фактическом прецеденте слишком велик, чтобы создать копию, и я вызываю код, который является внешним для моего проекта.

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

Что именно ваш вопрос? – cel

+0

Я верю, что op спрашивает, почему первый пример копирует, где другой делает это по ссылке. Может быть, так как вы выбираете непрерывный набор строк, он возвращает копию? Выбор по не изменяемому индексу возвращает копию? – postelrich

+0

Вопрос в том, как передать ссылку на определенный набор строк numpy на функцию для обработки или модификации на месте? – papahabla

ответ

1

В NumPy, "basic slices", такие как x[2, :], возвращение взглядов.

Так называемый "advanced indexing", , такой как x[(0,1,3), :], возвращает копии массива.

Под капотом значения Numpy массивы хранят в непрерывном блоке памяти и доступа к значениям на основе dtype, shape и strides. Значения сами могут быть несмежными внутри этого блока памяти в зависимости от шага, но тем не менее каждый массив ссылается на значения из одного блока памяти.

Продвинутое индексирование позволяет вам выбрать произвольно строк из этого блока памяти. В общем, нет способа указать результирующий массив, используя исходный блок памяти , и просто тип, форму и шаги. Поэтому значения результирующего массива должны быть скопированы в новый массив. Вот почему расширенная индексация всегда возвращает копию.

Модификация копии массива (как и следовало ожидать) не влияет на исходный массив. Вот почему прохождение x[(0, 1, 3), :] до inplace_place не влияет на x.

Однако назначения, даже если левая сторона использует расширенную индексацию, действительно влияют на исходный массив. Например,

x[(0, 1, 3), :] = C*N 

повлияет на x. Таким образом, вы можете исправить код, передав строки в 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) 
Смежные вопросы