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

102

Мои массивы 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, есть ли способ справиться с этим элегантно и эффективно?

Дун Пил
источник
8
pandashas pandas.isnull(): Я не уверен, что это соответствует вашим потребностям, поэтому некоторые примеры данных могут быть хорошими.
Мариус
4
@Marius: pandas.isnull()кажется, работает отлично. Единственный тип данных, с которым я в настоящее время имею дело с разрывами, numpy.isnan()- это строка, и pandas.isnull()она хорошо обрабатывается. Фактически, он, кажется, хорошо справляется со всеми любыми объектами, которые я ему бросил. Были ли какие-то конкретные проблемы, которые вас беспокоили? В противном случае вы можете отправить свой комментарий как полноценный ответ, поскольку он кажется каноническим ответом, по крайней мере, для пользователей pandas.
Dun Peal

Ответы:

170

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 есть инструменты, чтобы справиться с этим.

Datetimes тоже (если вы используете, 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
Мариус
источник
19

Ваш тип действительно произвольный? Если вы знаете, что это будет просто int float или строка, вы можете просто сделать

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

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

Молоток
источник
Я имею дело с множеством разных типов данных. В то время как большинство столбцов имеют типы данных int * или float *, другие могут быть любыми объектами, хотя до сих пор я использовал только строковый тип.
Дан Пил
Строки в Python не имеют dtype. Возможно, вам придется сделатьtype(val) == 'float'
pvarma
4
type(val) == float and np.isnan(val)- работал у меня
Дэнни Каллен
@ user1930402 Я предполагаю, что это массивы numpy, а не обычные python. Например: np.array (["hello"]) [0] .dtype работает, но ["hello"] [0] .dtype - нет
Hammer