Secara efisien memeriksa apakah objek arbitrer adalah NaN dengan Python / numpy / pandas?

101

Array numpy saya digunakan np.nanuntuk menunjukkan nilai yang hilang. Saat saya mengulangi kumpulan data, saya perlu mendeteksi nilai yang hilang tersebut dan menanganinya dengan cara khusus.

Saya menggunakan secara naif numpy.isnan(val), yang berfungsi dengan baik kecuali jika valtidak termasuk dalam subset tipe yang didukung oleh numpy.isnan(). Misalnya, data yang hilang dapat terjadi di bidang string, dalam hal ini saya mendapatkan:

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

Selain menulis pembungkus mahal yang menangkap pengecualian dan pengembalian False, adakah cara untuk menangani ini dengan elegan dan efisien?

Dun Peal
sumber
8
pandashas pandas.isnull(): Saya tidak yakin apakah itu memenuhi kebutuhan Anda, jadi beberapa contoh data mungkin bagus.
Marius
4
@Marius: pandas.isnull()sepertinya bekerja dengan sempurna. Satu-satunya tipe data yang saat ini saya hadapi numpy.isnan()adalah pemutusan string, dan pandas.isnull()menanganinya dengan baik. Bahkan, tampaknya menangani dengan baik semua objek sewenang-wenang yang saya lemparkan ke sana. Apakah ada masalah khusus yang Anda khawatirkan? Jika tidak, Anda mungkin ingin mengirimkan komentar Anda sebagai jawaban yang lengkap, karena tampaknya seperti jawaban kanonik, setidaknya untuk pengguna pandas.
Dun Peal

Jawaban:

169

pandas.isnull()(juga pd.isna(), dalam versi yang lebih baru) memeriksa nilai yang hilang di array numerik dan string / objek. Dari dokumentasi, ia memeriksa:

NaN dalam array numerik, Tidak ada / NaN dalam array objek

Contoh cepat:

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

Ide menggunakan numpy.nanuntuk merepresentasikan nilai yang hilang adalah sesuatu yang pandasdiperkenalkan, itulah mengapa pandasmemiliki alat untuk menghadapinya.

Datetimes juga (jika Anda menggunakan, pd.NaTAnda tidak perlu menentukan 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
Marius
sumber
19

Apakah tipe Anda benar-benar sewenang-wenang? Jika Anda tahu itu hanya akan menjadi int float atau string yang bisa Anda lakukan

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

dengan asumsi itu dibungkus dengan numpy, itu akan selalu memiliki tipe d dan hanya float dan kompleks yang dapat menjadi NaN

Palu
sumber
Saya berurusan dengan berbagai jenis data. Sementara sebagian besar kolom memiliki tipe data int * atau float *, yang lain bisa berupa objek apa pun, meskipun sejauh ini satu-satunya tipe lain yang saya gunakan adalah string.
Dun Peal
String dalam python tidak memiliki dtype. Anda mungkin harus melakukannyatype(val) == 'float'
pvarma
4
type(val) == float and np.isnan(val)- bekerja untuk saya
Danny Cullen
@ user1930402 Saya berasumsi ini adalah array numpy bukan yang python biasa. Misalnya: np.array (["hello"]) [0] .dtype berfungsi tetapi ["hello"] [0] .dtype tidak
Hammer