2015-04-09 33 views
185

Trong gấu trúc trăn, cách tốt nhất để kiểm tra xem liệu một DataFrame có một (hoặc nhiều) giá trị NaN không?gấu trúc Python: kiểm tra xem có giá trị nào là NaN trong DataFrame

Tôi biết về hàm pd.isnan, nhưng điều này trả về một DataFrame của booleans cho mỗi phần tử. This post ngay tại đây cũng không trả lời chính xác câu hỏi của tôi.

+2

check out [tóm tắt các tội danh thiếu dữ liệu trong gấu trúc] (http://stackoverflow.com/questions/22257527/how- do-i-get-a-tóm tắt-of-the-đếm-of-mất-dữ liệu-trong-gấu trúc) – JGreenwell

Trả lời

209

jwilner 's là tại chỗ trên. Tôi đã khám phá để xem liệu có một lựa chọn nhanh hơn hay không, vì theo kinh nghiệm của tôi, tổng hợp các mảng phẳng là (kỳ lạ) nhanh hơn đếm. Mã này dường như nhanh hơn:

df.isnull().values.any() 

Ví dụ:

In [2]: df = pd.DataFrame(np.random.randn(1000,1000)) 

In [3]: df[df > 0.9] = pd.np.nan 

In [4]: %timeit df.isnull().any().any() 
100 loops, best of 3: 14.7 ms per loop 

In [5]: %timeit df.isnull().values.sum() 
100 loops, best of 3: 2.15 ms per loop 

In [6]: %timeit df.isnull().sum().sum() 
100 loops, best of 3: 18 ms per loop 

In [7]: %timeit df.isnull().values.any() 
1000 loops, best of 3: 948 µs per loop 

df.isnull().sum().sum() là chậm hơn một chút, nhưng tất nhiên, có thêm thông tin - số NaNs.

+1

Cảm ơn bạn đã đánh dấu thời gian. Thật đáng ngạc nhiên khi 'pandas' không có chức năng tích hợp cho việc này. Đó là sự thật từ bài đăng của @ JGreenwell rằng 'df.describe()' có thể làm điều này, nhưng không có chức năng trực tiếp. – hlin117

+1

Tôi chỉ định thời gian 'df.describe()' (không tìm thấy 'NaN'). Với một mảng 1000 x 1000, một cuộc gọi duy nhất mất 1,15 giây. – hlin117

+2

: 1, Ngoài ra, 'df.isnull(). Values.sum()' là nhanh hơn một chút so với 'df.isnull(). Values.flatten(). Sum()' – Zero

13

df.isnull().any().any() nên làm điều đó.

77

Bạn có một vài tùy chọn.

import pandas as pd 
import numpy as np 

df = pd.DataFrame(np.random.randn(10,6)) 
# Make a few areas have NaN values 
df.iloc[1:3,1] = np.nan 
df.iloc[5,3] = np.nan 
df.iloc[7:9,5] = np.nan 

Bây giờ khung dữ liệu trông giống như sau:

  0   1   2   3   4   5 
0 0.520113 0.884000 1.260966 -0.236597 0.312972 -0.196281 
1 -0.837552  NaN 0.143017 0.862355 0.346550 0.842952 
2 -0.452595  NaN -0.420790 0.456215 1.203459 0.527425 
3 0.317503 -0.917042 1.780938 -1.584102 0.432745 0.389797 
4 -0.722852 1.704820 -0.113821 -1.466458 0.083002 0.011722 
5 -0.622851 -0.251935 -1.498837  NaN 1.098323 0.273814 
6 0.329585 0.075312 -0.690209 -3.807924 0.489317 -0.841368 
7 -1.123433 -1.187496 1.868894 -2.046456 -0.949718  NaN 
8 1.133880 -0.110447 0.050385 -1.158387 0.188222  NaN 
9 -0.513741 1.196259 0.704537 0.982395 -0.585040 -1.693810 
  • Lựa chọn 1: df.isnull().any().any() - này trả về một giá trị boolean

Bạn biết về isnull() mà sẽ trả lại một khung dữ liệu như sau:

 0  1  2  3  4  5 
0 False False False False False False 
1 False True False False False False 
2 False True False False False False 
3 False False False False False False 
4 False False False False False False 
5 False False False True False False 
6 False False False False False False 
7 False False False False False True 
8 False False False False False True 
9 False False False False False False 

Nếu bạn thực hiện nó df.isnull().any(), bạn có thể tìm chỉ các cột có NaN giá trị:

0 False 
1  True 
2 False 
3  True 
4 False 
5  True 
dtype: bool 

Thêm một .any() sẽ cho bạn biết nếu có những điều trên là True

> df.isnull().any().any() 
True 
  • Tùy chọn 2: df.isnull().sum().sum() - Số này trả về một số nguyên tổng số NaN giá trị:

này hoạt động theo cùng một cách như .any().any() không, bằng cách đầu tiên đưa ra một tổng của số NaN giá trị trong một cột, sau đó tổng của những giá trị:

df.isnull().sum() 
0 0 
1 2 
2 0 
3 1 
4 0 
5 2 
dtype: int64 

Cuối cùng, để có được tổng số giá trị NaN trong DataFrame:

phản ứng
df.isnull().sum().sum() 
5 
0

Tùy thuộc vào loại dữ liệu bạn đang xử lý, bạn cũng có thể nhận được số lượng giá trị của từng cột trong khi thực hiện EDA bằng cách đặt dropna thành False.

for col in df: 
    print df[col].value_counts(dropna=False) 

Hoạt động tốt cho các biến phân loại, không quá nhiều khi bạn có nhiều giá trị duy nhất.

19

Nếu bạn cần biết có bao nhiêu "1 hoặc nhiều" hàng có Nans:

df.isnull().T.any().T.sum() 

Hoặc nếu bạn cần phải rút ra khỏi các hàng và kiểm tra chúng:

nan_rows = df[df.isnull().T.any().T] 
4

Kể từ pandas có để tìm hiểu điều này cho DataFrame.dropna(), tôi đã xem xét cách họ triển khai và phát hiện ra rằng họ đã sử dụng DataFrame.count(), tính tất cả các giá trị không null trong số DataFrame. Cf. pandas source code. Tôi đã không chấm điểm kỹ thuật này, nhưng tôi tìm các tác giả của thư viện có khả năng đã thực hiện một sự lựa chọn khôn ngoan để làm thế nào để làm điều đó.

9

Vì không có đề cập nào, chỉ có một biến khác được gọi là hasnans.

df[i].hasnans sẽ xuất ra True nếu một hoặc nhiều giá trị trong chuỗi gấu trúc là NaN, False nếu không. Lưu ý rằng nó không phải là một hàm.

gấu trúc phiên bản '0.19.2' và '0.20.2'

+3

Câu trả lời này không chính xác. Pandas Series có thuộc tính này nhưng DataFrames thì không.Nếu 'df = DataFrame ([1, None], columns = ['foo'])', thì 'df.hasnans' sẽ ném' AttributeError', nhưng 'df.foo.hasnans' sẽ trả về' True'. –

5

Thêm vào Hobs câu trả lời tuyệt vời, tôi rất mới để Python và Pandas vì vậy hãy chỉ ra nếu tôi sai.

Để tìm hiểu mà hàng có Nans:

nan_rows = df[df.isnull().any(1)] 

sẽ thực hiện các hoạt động tương tự mà không cần transposing bằng cách xác định trục của bất kỳ() như 1 để kiểm tra xem 'True' hiện diện trong hàng.

3

Chỉ cần sử dụng math.isnan(x), Trả về true nếu x là NaN (không phải là số) và False nếu không.

+0

Tôi không nghĩ 'math.isnan (x)' sẽ hoạt động khi 'x' là một DataFrame. Thay vào đó, bạn sẽ nhận được một TypeError. – hlin117

12

Để tìm hiểu mà hàng có Nans trong một cột cụ thể:

nan_rows = df[df['name column'].isnull()] 
+5

Để tìm ra những hàng nào không có NaN trong một cột cụ thể: 'non_nan_rows = df [df ['cột tên']. Notnull()]'. – Elmex80s

Các vấn đề liên quan