2014-12-20 6 views
-1

Что, возможно, неправильно с помощью следующего присваивания и как это должно быть исправленоНазначение массива в numpy?

n = 1000 
a = np.array ([8,9,0]) 
Anew= np.random.random((n,n)) 
Adash= np.zeros((n,n))+ np.diag(np.diag(Anew)) 
S = Anew[a,:][:,a] 
Adash[a,:][:,a]= S 

Здесь S является ненулевым массив и Anew также некоторые ненулевым массив такого же размера, как Adash, но Adash не изменить до и после назначения.

+0

Что такое n, что такое Anew? (можете ли вы дать нам пример, который терпит неудачу) –

+1

Я думаю, что они придирчивы к трюму. 'unutbu' понял этот вопрос и дал хороший ответ.Тем не менее, нетрудно будет изменить пример - уменьшите 'n', определите' Anew', укажите ожидаемое изменение в 'Adash'. – hpaulj

+0

Жаль, что он на удержании, потому что это то, что я редко видел здесь. Любые ссылки на другие вопросы, касающиеся np.ix_? Поскольку я не могу найти много, я думаю, что этот ответ должен быть там. Это не вопрос отладки, а концептуальный - этот тип индексирования возникает во многих приложениях машинного обучения. Ответы на нарезку и расширенное целочисленное индексирование, в то время как в изобилии бесполезны здесь. Я очень доволен ответом @ unutbu и в два раза счастлив, что они поняли, о чем я прошу, не придирчивая к тому, что такое значение n, например – methane

ответ

2

Advanced индексирование возвращает копию:

Adash[a,:] использует "advanced integer indexing". Продвинутая индексация, в отличие от базовой нарезки, всегда возвращает копию. Таким образом,

Adash[a,:][:,a] = ... является модификация копии, а не вид, из Adash.

Чтобы добавить оскорбление к ранению, ссылка на копию, возвращенную Adash[a,:], не указана, поэтому изменение копии также будет утрачено.


Вместо этого вы можете использовать numpy.ix_:

Adash[np.ix_(a,a)] = S 

Например,

import numpy as np 
n = 4 
Anew = np.arange(16).reshape(4, 4) 
a = np.arange(3) 
Adash = np.zeros((n, n)) + np.diag(np.diag(Anew)) 
S = Anew[a, :][:, a] 

Adash[a, :][:, a] = S 
print(Adash) 

# [[ 0. 0. 0. 0.] 
# [ 0. 5. 0. 0.] 
# [ 0. 0. 10. 0.] 
# [ 0. 0. 0. 15.]] 

Adash[np.ix_(a,a)] = S 
print(Adash) 
# [[ 0. 1. 2. 0.] 
# [ 4. 5. 6. 0.] 
# [ 8. 9. 10. 0.] 
# [ 0. 0. 0. 15.]] 

Basic ломтиков возвращают вид:

С другой стороны, если вы можете заменить массив целочисленных индексаций a с основным срезом, то Adash[slice]будет вернуть вид Adash, а затем Adash[slice][...] = val изменяет Adash:

Adash[:3, :3] = S 

Подробнее о том, почему Adash[a,:][:,a] = ... не изменяет Adash:

Использование двух комплектов скобок называется index cha ining. Обратите внимание, что, когда вы выражаете назначение без привязки индекса, тогда Adash изменяется, потому что Adash[...] = val вызывает Adash.__setitem__.

В отличие от этого, Adash[a,:][:,a] называет Adash.__getitem__((a,slice(None))), который возвращает новый массив, давайте назовем его temp, чьи исходные данные копируются из Adash. Затем вызывается temp.__setitem__((slice(None), a)), который изменяет temp. Adash никогда не изменяется. Поскольку нет ссылки на temp, временный, вновь созданный массив получает собранный мусор.


PS. точки с запятой в конце операторов не нужны в Python.

+0

Спасибо! Я смущен, то почему следующее: U [:, a] = np.dot (U [:, a], V); работает нормально, а U обновляется? Здесь V - всего лишь массив подходящего размера. – methane

+0

'U [...] = val' вызывает' U .__ setitem__', поэтому он модифицирует 'U'. Это двойной набор скобок, которые вызывают проблему, когда первый набор скобок возвращает копию, а не представление. – unutbu

+0

А я так благодарю! У вас есть предложения по более эффективному способу выражения U [:, a] = np.dot (U [:, a], V)? Я не знал о функции np.ix - очень полезен. – methane

Смежные вопросы