Какая разница при индексации массива numpy между использованием целого и скалярного числа? - PullRequest
0 голосов
/ 14 сентября 2018

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

>>> a = np.array([[1, 2], [3, 4]])
>>> a[0][0]
1
>>> a[np.array(0)][np.array(0)]
1
>>> a[0][0] = 5
>>> a
array([[5, 2],
       [3, 4]])
>>> a[np.array(0)][np.array(0)] = 6
>>> a
array([[5, 2],
       [3, 4]])

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

Однако при индексации кортежа проблема исчезла.

>>> a[np.array(0), np.array(0)] = 6
>>> a
array([[6, 2],
       [3, 4]])

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

Из любопытства я попробовал сделать это с одномерным массивом.Результат будет другим.

>>> a = np.array([1, 2])
>>> a[np.array(0)] = 3
>>> a
array([3, 2])

На этот раз элемент был изменен.

Урок, который я усвоил, заключается в том, что я должен максимально использовать индекс кортежа для пустых массивов, чтобы быть в безопасности.,Но мне бы очень хотелось объяснить эти противоречивые эффекты.Спасибо!

1 Ответ

0 голосов
/ 14 сентября 2018

Глядя на расположение буфера данных:

In [45]: a.__array_interface__['data']
Out[45]: (44666160, False)
In [46]: a[0].__array_interface__['data']
Out[46]: (44666160, False)

То же место для a[0] дела. Изменение a[0] изменит a.

Но с индексом массива буфер данных отличается - это копия. Изменение этой копии не повлияет на a.

In [47]: a[np.array(0)].__array_interface__['data']
Out[47]: (43467872, False)

a[i,j] индексирование более идиоматично, чем a[i][j]. В некоторых случаях они одинаковы. Но существует достаточно случаев, когда они различаются, поэтому разумно избегать последующего, если вы действительно не знаете, что он делает и почему.

In [49]: a[0]
Out[49]: array([1, 2])
In [50]: a[np.array(0)]   
Out[50]: array([1, 2])
In [51]: a[np.array([0])]
Out[51]: array([[1, 2]])

Индексирование с помощью np.array(0), массива 0d, похоже на индексирование с помощью np.array([0]), массива 1d. Оба производят копию, первое измерение которой имеет размер, аналогичный индексу.

По общему признанию, это сложно, и, вероятно, не появляется, кроме как при выполнении такого набора.


При использовании np.matrix выбор [i][j] против [i,j] также влияет на форму - разница между питонами между двумя формами матрицы x [i, j] и x [i] [j]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...