Hướng dẫn dropna trong python

Một vấn đề khi phân tích dữ liệu là xử lý missing data. Pandas đã làm cho việc này dễ dàng nhất có thể.
 

Series

Tạo một pandas series chứa các giá trị NaN.

Nếu chúng ta nhìn lại một lần nữa trong ví dụ trước, ta có thể thấy rằng chỉ mục của chuỗi giống như các khóa của dictionary mà chúng ta sử dụng để tạo ra các sales. Bây giờ, chúng ta muốn sử dụng một chỉ mục không chồng chéo với các khóa dictionary. Chúng ta đã thấy rằng chúng ta có thể truyền vào list hoặc tuple với đối số từ khoá 'index' để xác định chỉ mục. Trong ví dụ tiếp theo, list (hoặc tuple) được truyền cho tham số keyword 'index' sẽ không tương đương các khoa trong dictionary. Điều này có nghĩa là một số hãng điện thoại từ dictionay sẽ bị thiếu, ví dụ hai hãng ("LG" và "HTC") không xuất hiện trong dictionary.

>>> import numpy as np

>>> import pandas as pd

>>> phones = ['Iphone',"Samsung Note","Samsung S","Nokia"]

>>> quantities = [10,12,30,100]

>>> sales = dict(zip(phones, quantities))

>>> S = pd.Series(sales)

>>> brands = ["Iphone","Samsung Note","Nokia","Samsung S","LG","HTC"]

>>> SS = pd.Series(sales,index=brands)

>>> SS

Iphone           10.0

Samsung Note     12.0

Nokia           100.0

Samsung S        30.0

LG                NaN

HTC               NaN

dtype: float64

>>>

Chúng ta có thể thấy rằng các brands, mà không có trong từ điển sales, nhận giá trị NaN. NaN là viết tắt của "not a number". Nó cũng có thể được xem là có nghĩa là "missing" trong ví dụ của chúng ta.

Nếu trong quá trình tạo Series mà ta truyền một dictionary, ứng với key có giá trị là “None” thì đối tượng Series tạo thành sẽ nhận giá trị NaN.

>>> d = {"a":23, "b":45, "c":None, "d":0}

>>> S = pd.Series(d)

>>> print(S)

a    23.0

b    45.0

c     NaN

d     0.0

dtype: float64

>>>

 Dataframe

Tạo một dataframe tồn tại giá trị NaN.

>>> import numpy as np

>>> import pandas as pd

>>> df = pd.DataFrame(np.random.randn(5, 4)*100,columns = list("ABCD"))

>>> df

            A          B           C           D

0  193.958156  76.560508 -144.899007  -29.874618

1  196.163029  22.368007   15.188653 -102.040442

2  -22.597828  27.841637  -23.202380   50.040193

3 -111.654480 -25.036501   41.283627  -25.941029

4  -92.212283  77.257557 -122.999865   59.863213

>>> df = df[df>0]

>>> df

            A          B          C          D

0  193.958156  76.560508        NaN        NaN

1  196.163029  22.368007  15.188653        NaN

2         NaN  27.841637        NaN  50.040193

3         NaN        NaN  41.283627        NaN

4         NaN  77.257557        NaN  59.863213

>>>

Phương thức isnull() và notnull() để kiểm tra phần tử là NaN hay không là NaN tương ứng.

>>> SS.isnull()

Iphone          False

Samsung Note    False

Nokia           False

Samsung S       False

LG               True

HTC              True

dtype: bool

>>> SS.notnull()

Iphone           True

Samsung Note     True

Nokia            True

Samsung S        True

LG              False

HTC             False

dtype: bool

>>> print "working with dataframe"

working with dataframe

>>> df['A'].isnull()

0    False

1    False

2     True

3     True

4     True

Name: A, dtype: bool

>>> df['A'].notnull()

0     True

1     True

2    False

3    False

4    False

Name: A, dtype: bool

>>> df.isnull()

       A      B      C      D

0  False  False  True  True

1  False  False  False  True

2  True   False   True  False

3  True   True  False  True

4  True  False   True  False

>>> print “Hang co chua phan tu null”

>>> df.isnull().any()

A    True

B     True

C     True

D    True

dtype: bool

>>> print “Cot co chua phan tu null”

>>> df.isnull().any(1)

0    True

1    True

2     True

3     True

4     True

dtype: bool

Loại bỏ missing data dùng .dropna(axis=0, how=’any’, thresh=None, subset=None, inplace=False)

Trong đó:

   axis: nhận giá trị mặc định là 0 –‘index’, 1-‘columns’

   how: ‘any’ sẽ drop axis đang xét nếu có bất gì phần tử NaN nào tồn tại, ‘all’ sẽ drop axis nếu toàn bộ phần tử đang xét nhận giá trị NaN.

>>> print “Drop các hàng có chứa phần tử là NaN trong series SS”

Drop các hàng có chứa phần tử là NaN trong series SS

>>> SS.dropna()

Iphone           10.0

Samsung Note     12.0

Nokia           100.0

Samsung S        30.0

dtype: float64

>>> print "working with dataframe"
working with dataframe
>>> df

            A          B          C          D

0  193.958156  76.560508        NaN        NaN

1  196.163029  22.368007  15.188653        NaN

2         NaN  27.841637        NaN  50.040193

3         NaN        NaN  41.283627        NaN

4         NaN  77.257557        NaN  59.863213

>>> df.dropna()

Empty DataFrame

Columns: [A, B, C, D]

Index: []

>>>

Gán gián trị mặc định cho “missing data” dùng hàm fillna(number)

>>> SS.fillna(10000000)
Iphone                10.0
Samsung Note          12.0
Nokia                100.0
Samsung S             30.0
LG              10000000.0
HTC             10000000.0
dtype: float64
>>> print "gan qua dictionary"
gan qua dictionary
>>> nafills = {"LG":9919191,"HTC":20}
>>> SS.fillna(nafills)
Iphone               10.0
Samsung Note         12.0
Nokia               100.0
Samsung S            30.0
LG              9919191.0
HTC                  20.0
dtype: float64
>>> print "working with dataframe"
working with dataframe
>>> print ("NaN replaced with '0':")
NaN replaced with '0':
>>> df.fillna(0)
            A          B          C          D
0  193.958156  76.560508   0.000000   0.000000
1  196.163029  22.368007  15.188653   0.000000
2    0.000000  27.841637   0.000000  50.040193
3    0.000000   0.000000  41.283627   0.000000
4    0.000000  77.257557   0.000000  59.863213
>>>

Ngoài cách fill các vị trí NaN với một hằng số như phía trên. Pandas còn cung cấp cho ta các lựa chọn khác, fill theo 2 cách sau: sử dụng phương thức pad/ffill để fill dữ liệu kiểu forward tức là missing data sẽ được fill bằng dữ liệu của hàng trước đó, hoặc kiểu thứ hai là bfill/backfill sẽ mang ý nghĩa ngược lại. Cùng xem ví dụ sau:

>>> df

            A          B          C          D

0  193.958156  76.560508        NaN        NaN

1  196.163029  22.368007  15.188653        NaN

2         NaN  27.841637        NaN  50.040193

3         NaN        NaN  41.283627        NaN

4         NaN  77.257557        NaN  59.863213



>>> df.fillna(method='bfill')

            A          B          C          D

0  193.958156  76.560508  15.188653  50.040193

1  196.163029  22.368007  15.188653  50.040193

2         NaN  27.841637  41.283627  50.040193

3         NaN  77.257557  41.283627  59.863213

4         NaN  77.257557        NaN  59.863213

>>> df.fillna(method='ffill')

            A          B          C          D

0  193.958156  76.560508        NaN        NaN

1  196.163029  22.368007  15.188653        NaN

2  196.163029  27.841637  15.188653  50.040193

3  196.163029  27.841637  41.283627  50.040193

4  196.163029  77.257557  41.283627  59.863213

>>>

Kết Luận

Trong quá trình thao tác trên data, việc tập data đầu vào chưa chuẩn hóa có chứa nhiều vị trí missing là không thể tránh khỏi. Các bạn có thể sử dụng hai phương thức isnull()/notnull() để kiểm tra một phần tử là NaN hay không tương ứng. Sau đó tùy vào bài toán cụ thể mà sử dụng dropna() để drop các phần tử missing hay fillna() để gán giá trị mặc định cho vị trí missing. Chi tiết hơn về dropna() và fillna() các bạn có thể tham khảo thêm các trang sau:

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html,

https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html