Ответ 1
Будущее предупреждение происходит, когда вы делаете что-то вроде этого:
numpy.asarray([1,2,3,4]) == None
В настоящее время возвращается
False
, но я понимаю, что вернет массив, содержащий[False,False,False,True]
в будущей версии Numpy.
Как я уже упоминал в комментариях, ваш пример неверен. Будущие версии numpy вернут [False ,False, False, False]
, т.е. False
для каждого элемента массива, который не равен None
. Это в большей степени согласуется с тем, как в настоящее время работают сопоставления элементов с другими скалярными значениями, например:
In [1]: np.array([1, 2, 3, 4]) == 1
Out[1]: array([ True, False, False, False], dtype=bool)
In [2]: np.array(['a', 'b', 'c', 'd']) == 'b'
Out[2]: array([False, True, False, False], dtype=bool)
Что меня смущает, так это поведение ключевого слова
in
с 1D-массивом по сравнению со списком
Когда вы тестируете x in y
, вы вызываете y.__contains__(x)
. Когда y
- это список, __contains__
в основном что-то делает по строкам:
for item in y:
if (item is x) or (item == x):
return True
return False
Насколько я могу судить, np.ndarray.__contains__(x)
выполняет эквивалент этого:
if any(y == x):
return True
else:
return False
То есть он сначала проверяет элементарное равенство по всему массиву (y == x
будет булевым массивом размером y
). Поскольку в вашем случае вы проверяете, будет ли y == None
, это повысит значение FutureWarning
по причинам, указанным выше.
В комментариях вы также хотели знать, почему
np.nan in np.array([1, 2, 3, np.nan])
возвращает False
, но
np.nan in [1, 2, 3, np.nan]
возвращает True
. Первая часть легко объясняется тем, что np.nan != np.nan
(см. Здесь для обоснования этого). Чтобы понять, почему второй случай возвращает True
, помните, что list.__contains__()
сначала проверяет идентификатор (is
) перед проверкой равенства (==
). Поскольку np.nan is np.nan
, второй случай вернет True
.