Python: применение маски без изменения значения исходного массива - PullRequest
0 голосов
/ 22 октября 2018

Я пытаюсь применить простую логическую маску к массиву np.Ниже приведен простой пример.

temp = np.arange(5)
print(temp)
temp1 = temp
temp1[temp1 < 2] = 0
print(temp1)
print(temp)

Я уже присвоил значение temp новой переменной temp1, поэтому я ожидал, что маска применяется только к переменной temp1.Однако значение temp также обновляется.Интересно, почему это происходит?

Результат:

[0 1 2 3 4]
[0 0 2 3 4]
[0 0 2 3 4]

Ответы [ 3 ]

0 голосов
/ 22 октября 2018

Как было сказано ранее, вы получаете только новую ссылку на temp.Это означает, что хотя переменные имеют разные имена, они обе указывают на один и тот же фрагмент памяти.Таким образом, изменяя значение в одном, вы фактически изменяете значение в обоих.Чтобы избежать этого, вам нужно использовать, как минимум, мелкую копию.Вот два способа сделать это, используя numpy:

temp1 = numpy.copy(temp)

или

temp1 = np.array(temp, copy = True)
0 голосов
/ 22 октября 2018

Как уже отмечали другие, вам нужно явно запросить копию , когда вы имеете дело с подобными коллекциям объектами в python.То же поведение, которое вы видите здесь, может происходить и со списками и словарями.У Numpy есть хороший вспомогательный метод numpy.copy (), который должен решить ваши проблемы.

# one way
temp1 = temp.copy()

#another way
temp1 = numpy.copy(temp)

Чтобы добавить что-то, что мне показалось полезным, вы можете сохранить саму маску, а затем применить ее умножением.

mask = temp < 2
masked_temp = temp * mask

Это полезно в том случае, если вы хотите визуализировать или повторно использовать эту маску и делает проблему копирования ранее неактуальной (поскольку masked_temp является не копией, а вновь вычисляемым массивом).

0 голосов
/ 22 октября 2018

Ваши переменные temp1 и temp относятся к одному и тому же объекту.Используйте .copy(), чтобы получить поверхностную копию элемента, чтобы он не изменил оригинал.

temp = np.arange(5)
print(temp)
temp1 = temp.copy()
temp1[temp1 < 2] = 0
print(temp1)
print(temp)

Если вы хотите узнать больше об именах и ссылках, https://nedbatchelder.com/text/names.html/

...