#python #numpy
#python #numpy
Вопрос:
Я пытался выполнить логическое индексирование, но..
np.random.randn(8).reshape((4,2))
Out[11]:
array([[-1.13058416, 1.08397186],
[-1.2730122 , 0.78306498],
[-0.05370502, -1.16723298],
[ 1.01750955, -0.95029671]])
a=np.random.randn(8).reshape((4,2))
a[[2==3,3==0,0==0,1!=1]]
Out[13]:
array([[ 0.18235299, -2.53482367],
[ 0.18235299, -2.53482367],
[-1.03752809, -2.2790847 ],
[ 0.18235299, -2.53482367]])
Что только что произошло?
Я больше думал об индексации Bool. Что это за операция?
Я не прошу исправлять это для индексации Bool. Скорее, я спрашиваю, что происходит в этой операции? Это законно?
Комментарии:
1. Что это
[2==3,3==0,0==0,1!=1]
значит?2.
2 == 3
интерпретируется как 0 (False), поэтомуa[[2==3,3==0,0==0,1!=1]]
эквивалентноa[[0,0,1,0]]
3. точно, произвольные числа только для генерации bool
4. У вас была возможность взглянуть на мой ответ?
5. @AndrasDeak Я читаю это сейчас. дайте мне когда-нибудь
Ответ №1:
Легко думать о ndarray
s как list
о буферизованных s. Трансляция и операции с массивами автоматически распространяются на списки, участвующие в этих операциях, поэтому вы можете добавить массив и список совместимых с трансляцией фигур, и numpy не будет пытаться объединить их (как это было бы с двумя списками).
Одним огромным (и, для меня, запутанным) исключением является причудливое индексирование. Само по себе причудливое индексирование уже сбивает меня с толку (как человека, пришедшего из MATLAB), поскольку странно, что следующие два дают другой результат:
import numpy as np
A = np.random.rand(3,3)
A[0:1,0:1]
A[range(2),range(2)]
Первая представляет собой операцию нарезки и возвращает подматрицу размером 2 на 2. Последнее является случаем причудливого индексирования и возвращает только массив из 2 элементов, содержащий A[0,0]
и A[1,1]
.
Ваш вопрос связан с чем-то столь же странным: списки и массивы логических значений ведут себя по-разному при использовании в fancy indexing. Рассмотрим следующие два примера в соответствии с вашим вопросом:
A = np.random.rand(4,2)
bool_index_list = [False, True, True, False]
bool_index_array = np.array(bool_index_list)
A[bool_index_list].shape
A[bool_index_array].shape
Первое возвращает (4,2)
последнее (2,2)
.
В первом случае, поскольку индекс равен a list
, логические значения преобразуются в соответствующие целые числа, а результирующие значения [0,1,1,0]
используются в качестве фактических индексов в матрице, возвращая строку [first,second,second,first] соответственно.
В последнем случае индекс array
of dtype=bool
используется так, как вы ожидаете: он используется как маска для игнорирования тех строк of A
, для которых указан индекс False
.
Примечания к выпуску numpy, среди прочего, указывают, что
В будущем логические массивы (такие как списки bools python) всегда будут обрабатываться как логические индексы, а логические скаляры (включая python
True
) будут законным логическим индексом.
Соответственно, приведенные выше случаи индексации на основе списков дают мне следующее предупреждение в numpy 1.10.1:
Предупреждение на будущее: в будущем логические массивы-лайки будут обрабатываться как индекс логического массива
Итак, короткий ответ на ваш вопрос заключается в том, что это законно, но ненадолго. Придерживайтесь ndarray
навороченной индексации, и на этом пути у вас не должно возникнуть никаких проблем.