В чем разница между `arr [tuple (seq)]` и `arr [seq]`? Относительно использования последовательности, отличной от кортежа, для многомерного индексирования не рекомендуется

Я использую ndarray, чтобы нарезать другой ndarray. Обычно использую arr[ind_arr]. numpy, похоже, это не нравится, и он поднимает FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated use arr[tuple(seq)] instead of arr[seq].

В чем разница между arr[tuple(seq)] и arr[seq]?

Другие вопросы по StackOverflow, похоже, связаны с этой ошибкой в ​​scipy и pandas, и большинство людей предполагает, что ошибка связана с конкретной версией этих пакетов. Я столкнулся с предупреждением, работающим исключительно в numpy.

Примеры сообщений:

FutureWarning: использование последовательности без кортежей для многомерного индексирования не рекомендуется, используйте `arr [tuple (seq)]` вместо `arr [seq] `

Предупреждение о будущем: использование последовательности без кортежей для многомерного индексирования не рекомендуется, используйте `arr [tuple (seq)]`

FutureWarning с distplot в seaborn

Предупреждение о воспроизведении MWE:

import numpy as np

# generate a random 2d array
A = np.random.randint(20, size=(7,7))
print(A, '\n')

# define indices
ind_i = np.array([1, 2, 3])  # along i
ind_j = np.array([5, 6])  # along j

# generate index array using meshgrid
ind_ij = np.meshgrid(ind_i, ind_j, indexing='ij')

B = A[ind_ij]
print(B, '\n')

C = A[tuple(ind_ij)]
print(C, '\n')

# note: both produce the same result

person krg    schedule 13.06.2019    source источник


Ответы (1)


meshgrid возвращает список массивов:

In [50]: np.meshgrid([1,2,3],[4,5],indexing='ij')                                                      
Out[50]: 
[array([[1, 1],
        [2, 2],
        [3, 3]]), array([[4, 5],
        [4, 5],
        [4, 5]])]
In [51]: np.meshgrid([1,2,3],[4,5],indexing='ij',sparse=True)                                          
Out[51]: 
[array([[1],
        [2],
        [3]]), array([[4, 5]])]

ix_ делает то же самое, но возвращает кортеж:

In [52]: np.ix_([1,2,3],[4,5])                                                                         
Out[52]: 
(array([[1],
        [2],
        [3]]), array([[4, 5]]))

np.ogrid также производит список.

In [55]: arr = np.arange(24).reshape(4,6)                                                              

индексация с помощью кортежа ix:

In [56]: arr[_52]                                                                                      
Out[56]: 
array([[10, 11],
       [16, 17],
       [22, 23]])

индексация списком meshgrid:

In [57]: arr[_51]                                                                                      
/usr/local/bin/ipython3:1: FutureWarning: Using a non-tuple sequence for multidimensional indexing is deprecated; use `arr[tuple(seq)]` instead of `arr[seq]`. In the future this will be interpreted as an array index, `arr[np.array(seq)]`, which will result either in an error or a different result.
  #!/usr/bin/python3
Out[57]: 
array([[10, 11],
       [16, 17],
       [22, 23]])

Часто результат meshgrid используется при распаковке:

In [62]: I,J = np.meshgrid([1,2,3],[4,5],indexing='ij',sparse=True)                                    
In [63]: arr[I,J]                                                                                      
Out[63]: 
array([[10, 11],
       [16, 17],
       [22, 23]])

Здесь [I,J] то же самое, что и [(I,J)], составляя кортеж из двух подмассивов.

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

person hpaulj    schedule 13.06.2019
comment
Полезно знать альтернативы, спасибо. Итак, знаем ли мы, чем будут отличаться результаты (на что указывает FutureWarning ...which will result either in an error or a different result)? А иначе я должен попытаться придерживаться кортежей или распакованных индексов, а не arr[seq]? - person krg; 13.06.2019
comment
Он может попробовать arr[np.array(idx),...], превратив список meshgrid в массив, индексирующий только первое измерение. - person hpaulj; 13.06.2019
comment
Я что-то упустил? arr[_51], arr[_52] и arr[I, J] дают одинаковые результаты, так в чем же разница? - person Jason; 07.02.2020
comment
@Jason, да, они производят то же самое (кроме предупреждения). Это была моя точка зрения. - person hpaulj; 07.02.2020