Ефективно перевірити, чи довільним об'єктом є NaN в Python / numpy / pandas?


101

Мої масиви 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
pandasмає pandas.isnull(): Я не впевнений, чи відповідає це вашим потребам, тому деякі приклади даних можуть бути хорошими.
Маріус

4
@Marius: pandas.isnull()начебто працює чудово. Єдиний тип даних, з яким я зараз маю справу з розривами, numpy.isnan()є рядком і pandas.isnull()добре обробляє його. Насправді, схоже, добре впорається з будь-яким довільним об’єктом, який я накинув на нього. Чи були якісь конкретні проблеми, які вас хвилювали? В іншому випадку ви можете надіслати свій коментар як повноцінну відповідь, оскільки це здається канонічною відповіддю, принаймні для користувачів панди.
Дан Піл

Відповіді:


169

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вам не потрібно буде вказувати тип)

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 або string, який ви могли просто зробити

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

якщо припустити, що він загорнутий у numpy, він завжди матиме тип, і лише плаваючий і складний може бути NaN


Я маю справу з багатьма різними типами даних. Хоча в більшості стовпців є типи даних int * або float *, інші можуть бути будь-якими об'єктами, хоча поки що єдиний інший тип, який я використовував, був рядок.
Дан Піл

Рядок у python не має dtype . Можливо, вам доведеться зробитиtype(val) == 'float'
pvarma

4
type(val) == float and np.isnan(val)- працював на мене
Денні Каллен

@ user1930402 Я припускаю, що це нумеровані масиви, а не звичайні python. Наприклад: np.array (["привіт"]) [0] .dtype працює, але ["привіт"] [0] .dtype не
Hammer
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.