Эффективно проверяет, является ли произвольный объект NaN в Python/numpy/pandas?

Мои массивы numpy используют np.nan для обозначения отсутствующих значений. Поскольку я перебираю набор данных, мне нужно обнаружить такие отсутствующие значения и обрабатывать их особыми способами.

Наивно я использовал numpy.isnan(val), который хорошо работает, если val не относится к подмножеству типов, поддерживаемых numpy.isnan(). Например, отсутствующие данные могут возникать в строковых полях, и в этом случае я получаю:

>>> np.isnan('some_string')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Not implemented for this type

Помимо написания дорогостоящей обертки, которая ловит исключение и возвращает False, есть ли способ справиться с этим изящно и эффективно?

Ответ 1

pandas.isnull() (также pd.isna(), в более новых версиях) проверяет пропущенные значения как в числовом, так и в строковом/объектном массивах. Из документации он проверяет:

NaN в числовых массивах, None/NaN в массивах объектов

Быстрый пример:

import pandas as pd
import numpy as np
s = pd.Series(['apple', np.nan, 'banana'])
pd.isnull(s)
Out[9]: 
0    False
1     True
2    False
dtype: bool

Идея использования numpy.nan для представления пропущенных значений - это то, что представила pandas, поэтому у pandas есть инструменты для ее решения.

Datetime (если вы используете pd.NaT вам не нужно указывать dtype)

In [24]: s = Series([Timestamp('20130101'),np.nan,Timestamp('20130102 9:30')],dtype='M8[ns]')

In [25]: s
Out[25]: 
0   2013-01-01 00:00:00
1                   NaT
2   2013-01-02 09:30:00
dtype: datetime64[ns]''

In [26]: pd.isnull(s)
Out[26]: 
0    False
1     True
2    False
dtype: bool

Ответ 2

Является ли ваш тип действительно произвольным? Если вы знаете, что это просто int float или string, вы могли бы просто сделать

 if val.dtype == float and np.isnan(val):

Предполагая, что он завернут в numpy, он всегда будет иметь dtype, и только float и complex могут быть NaN