2016-09-29 9 views
3

При использовании Numpy имени массивов я наблюдаю другое поведение в двух следующих случаях:Неожиданного поведения с Numpy расширенной нарезкой в ​​названных массивах

  1. случая: первый, используя массив индексов для продвинутой нарезки, а затем выбрав подмассив по имя
  2. случая: сначала выбрать подмассив по имени, а затем с использованием массива индексов для нарезки расширенного

follwing код представляет собой пример

import numpy as np 

a = np.ones(5) 
data = np.array(zip(a, a, a), dtype=[("x", float), ("y", float), ("z", float)]) 

# case 1 
# does not set elements 1, 3 and 4 of data to 22 
data[[1, 3, 4]]["y"] = 22  
print data["y"] # -> [ 1. 1. 1. 1. 1.] 

# case 2 
# set elements 1, 3 and 4 of data to 22 
data["y"][[1, 3, 4]] = 22 
print data["y"] # -> [ 1. 22. 1. 22. 22.] 

Выход двух команд печати: [1. 1. 1. 1. 1.] и [1. 22. 1. 22. 22.]. Почему изменение порядка выбора приводит к разным результатам при настройке элементов?

ответ

3

Индексация со списком или массивом always returns a copy rather than a view:

In [1]: np.may_share_memory(data, data[[1, 3, 4]]) 
Out[1]: False 

Поэтому назначение data[[1, 3, 4]]["y"] = 22 является модификацией копия из data[[1, 3, 4]], а исходные значения в data не будут затронуты.

С другой стороны, ссылки на поле структурированного массива returns a view:

In [2]: np.may_share_memory(data, data["y"]) 
Out[2]: True 

так, чтобы присвоение data["y"][[1, 3, 4]]будет влиять на соответствующие элементы в data.

+0

Как вы сказали, индексирование с помощью списка или массива всегда возвращает копию, а не представление. Это объясняет, почему 'data [[1, 3, 4]] [" y "] = 22' работает над копией' data'. Но по той же причине 'data [" y "] [[1, 3, 4]]' должны работать только с копией 'data [" y "]'. Это также показывает «np.may_share_memory (данные, данные [" y "] [[1, 3, 4]]), которые оказываются« ложными ». Поэтому я не понимаю, почему это назначение работает. – murban

+0

Прекрасно назначать элементы, используя выражение индексирования, которое возвращает копию, если вы выполняете задание напрямую, не связывая при этом никаких других операций индексации. Например, 'x [[1, 2, 3]] = 4, 5, 6' будет работать, но' x [[1, 2, 3]] [:] = 4, 5, 6' не повлияет на ' x', так как первое выражение индексирования возвращает копию. –