Xử lý Missing Data là một phần quan trọng trong Data cleaning. Việc xử lý Missing Data nhanh chóng, gọn gàng giúp tiết kiệm rất nhiều thời gian cho dự án. Có nhiều công cụ mạnh làm tốt công việc này và một trong số đó là Pandas. Theo một nghiên cứu của IBM Data Analytsics thì 80% thời gian quý giá của một nhà khoa học dữ liệu được dành chỉ đơn giản là tìm kiếm, làm sạch và sắp xếp dữ liệu, chỉ còn lại 20% thời gian để thực sự làm phân tích.
Pandas là một thư viện phân tích dữ liệu được sử dụng rộng rãi cho Python. Hãy cùng Hybrid Technologies tham khảo cách cài đặt, khai báo và các thông tin cơ bản về Pandas trong bài viết này nhé!
Missing Data là gì?
Missing data là dữ liệu bị thiếu, được hiển thị như NaN, Nat, Null, N/A,… Missing Data xuất hiện do nhiều nguyên nhân như:
- Người dùng quên điền
- Dữ liệu bị mất trong quá trình chuyển thủ công từ cơ sở dữ liệu cũ
- Lỗi của chương trình
- Thiếu dữ liệu do trùng hợp
Missing Data có thể được phân thành 3 loại: Missing at Random (dữ liệu khuyết ngẫu nhiên), Missing Completely at Random (dữ liệu thiếu hoàn toàn ngẫu nhiên) và Missing Not at Random (dữ liệu khuyết không ngẫu nhiên).
Missing Data trong Pandas
Do dữ liệu có nhiều dạng và hình thức nên pandas rất linh hoạt trong việc xử lý Missing Data. Missing Data được đánh dấu mặc định là NaN để tăng tốc độ tính toán và thuận tiện. Tuy nhiên pandas cũng có thể dễ dàng phân biệtMissing Data vào các loại khác nhau: dấu phẩy động, số nguyên, boolean và đối tượng chung. np.nan, None và NaT (cho loại datetime64[ns]) là các giá trị missing tiêu chuẩn trong Pandas. Loại missing data mới (<NA>), được giới thiệu trong Pandas 1.0, thể hiện cho Missing Data kiểu số nguyên.
Thao tác với Missing Data trong Pandas
Pandas cho phép bạn thao tác linh hoạt với Missing Data trong Series, DataFrame như tìm giá trị bị thiếu (missing value), xác định giá trị tồn tại (không bị thiếu), loại bỏ giá trị bị thiếu, chèn giá trị bị thiếu, điền vào giá trị bị thiếu,… Dưới đây chúng mình sẽ trình bày các ví dụ cụ thể cho các thao tác.
Xác định giá trị bị thiếu và giá trị đang tồn tại: isna(), notna()
VD: Xác định giá trị bị thiếu bằng Series.isna và DataFrame.isna
import pandas as pd
import numpy as np
print('Kiểm tra isna cho Series')
ser = pd.Series([1, 2, np.nan, 4, np.nan, 5], dtype=pd.Int64Dtype())
na_Ser = ser.isna()
print(na_Ser)
''' ----------'''
print('Kiểm tra isna cho DataFrame')
df = pd.DataFrame({'cột_1':[0, 1, 3, 4, np.nan, 5, np.nan],
'cột_2':[9.1, 3.0, np.nan, -5.1, None, 2, 11],
'cột_3':['a', np.nan, 'ă', '!', '%', 'be be', 'o'],
'cột_4':[True, False, True, None, False, np.nan, True]})
na_DF = df.isna()
print(na_DF)
|
Output:
Kiểm tra isna cho Series
0 False
1 False
2 True
3 False
4 True
5 False
dtype: bool
Kiểm tra isna cho DataFrame
cột_1 cột_2 cột_3 cột_4
0 False False False False
1 False False True False
2 False True False False
3 False False False True
4 True True False False
5 False False False True
6 True False False False
|
VD: Xác định giá trị tồn tại (existing values) bằng Series.notna và DataFrame.notna
import pandas as pd
import numpy as np
print('Kiểm tra notna cho Series')
ser = pd.Series([1, 2, np.nan, 4])
notna_Ser = ser.notna()
print(notna_Ser)
''' ----------'''
print('Kiểm tra notna cho DataFrame')
df = pd.DataFrame({'cột_1':[0, 1, 3, 4, np.nan, 5, np.nan],
'cột_2':[9.1, 3.0, np.nan, -5.1, None, 2, 10]})
notna_DF = df.notna()
print(notna_DF)
|
Output:
Kiểm tra notna cho Series
0 True
1 True
2 False
3 True
dtype: bool
Kiểm tra notna cho DataFrame
cột_1 cột_2
0 True True
1 True True
2 True False
3 True True
4 False False
5 True True
6 False True
|
Xóa giá trị bị thiếu: dropna()
VD: Xóa giá trị thiếu bằng Series.dropna và DataFrame.dropna
import pandas as pd
import numpy as np
print('Series chứa missing data')
ser = pd.Series([1, 2, np.nan, 4])
print(ser)
print('Series đã xóa missing data')
drop_Ser = ser.dropna()
print(drop_Ser)
print('DataFrame chứa missing data')
df = pd.DataFrame({'cột_1':[0, 1, 3, 4, np.nan, 5, np.nan],
'cột_2':[9.1, 3.0, np.nan, -5.1, None, 2, 10]})
print(df)
print('DataFrame đã xóa missing data')
drop_DF = df.dropna()
print(drop_DF)
|
Output:
Series chứa missing data
0 1.0
1 2.0
2 NaN
3 4.0
dtype: float64
Series đã xóa missing data
0 1.0
1 2.0
3 4.0
dtype: float64
DataFrame chứa missing data
cột_1 cột_2
0 0.0 9.1
1 1.0 3.0
2 3.0 NaN
3 4.0 -5.1
4 NaN NaN
5 5.0 2.0
6 NaN 10.0
DataFrame đã xóa missing data
cột_1 cột_2
0 0.0 9.1
1 1.0 3.0
3 4.0 -5.1
5 5.0 2.0
|
Điền vào giá trị thiếu: fillna()
Sử dụng fillna() bạn có thể chèn vào các giá trị bị thiếu bằng dữ liệu khác theo một số cách:
VD: Thay thế giá trị bị thiếu bằng một giá trị vô hướng (scalar value)
import pandas as pd
import numpy as np
print('Series chứa missing data')
ser = pd.Series([pd.Timestamp('20200101'), np.nan, '20200401'])
print(ser)
print('Series đã thay missing data bằng giá trị vô hướng "1110" ')
fill_Ser = ser.fillna(1110)
print(fill_Ser)
print('DataFrame chứa missing data')
df = pd.DataFrame({'cột_1':[0, np.nan, 5, np.nan],
'cột_2':[9.1, np.nan, None, 10]})
print(df)
print('DataFrame đã thay missing data bằng giá trị vô hướng "AnhKiet"')
fill_DF = df.fillna('AnhKiet')
print(fill_DF)
|
Output:
Series chứa missing data
0 2020-01-01
1 NaT
2 2020-04-01
dtype: datetime64[ns]
Series đã thay missing data bằng giá trị vô hướng "1110"
0 2020-01-01 00:00:00
1 1110
2 2020-04-01 00:00:00
dtype: object
DataFrame chứa missing data
cột_1 cột_2
0 0.0 9.1
1 NaN NaN
2 5.0 NaN
3 NaN 10.0
DataFrame đã thay missing data bằng giá trị vô hướng "AnhKiet"
cột_1 cột_2
0 0 9.1
1 AnhKiet AnhKiet
2 5 AnhKiet
3 AnhKiet 10
|
VD: Sử dụng tham số method, các giá trị bị thiếu có thể được thay thế bằng các giá trị trước (pad/ffill) hoặc sau (bfill/backfill) chúng. Key limit sẽ giới hạn bao nhiêu giá trị trước/sau sẽ được lấy thay thế.
import pandas as pd
import numpy as np
df = pd.DataFrame({'A':[0, 1, np.nan, 5, 6, np.nan, 12],
'B':[pd.Timestamp('20200101'), '20190203', np.nan,
'20190403', np.nan, np.nan, '20090909']})
print('DataFrame có missing value')
print(df)
fw = df.fillna(method='ffill')
print('Fill về trước')
print(fw)
bw = df.fillna(method='bfill', limit=1)
print('Fill về sau với limit = 1')
print(bw)
|
Output:
DataFrame có missing value
A B
0 0.0 2020-01-01
1 1.0 2019-02-03
2 NaN NaT
3 5.0 2019-04-03
4 6.0 NaT
5 NaN NaT
6 12.0 2009-09-09
Fill về trước
A B
0 0.0 2020-01-01
1 1.0 2019-02-03
2 1.0 2019-02-03
3 5.0 2019-04-03
4 6.0 2019-04-03
5 6.0 2019-04-03
6 12.0 2009-09-09
Fill về sau với limit = 1
A B
0 0.0 2020-01-01
1 1.0 2019-02-03
2 5.0 2019-04-03
3 5.0 2019-04-03
4 6.0 NaT
5 12.0 2009-09-09
6 12.0 2009-09-09
|
Chèn Missing Data
Pandas cho phép bạn chèn giá trị vào Missing Data bằng fillna() thì bạn cũng có thể làm ngược lại: chèn Missing Data vào vị trí đã có giá trị. Giá trị thiếu thực tế được sử dụng sẽ được chọn dựa trên dtype.
VD: Chèn Missing Data cho các container (Series, DataFrame) chứa con số
import pandas as pd
import numpy as np
print('Series không có missing value')
ser = pd.Series([1, 2, 4])
print(ser)
ser.loc[0] = None
print(ser)
print('Tạo DataFrame không có missing value')
df = pd.DataFrame({'A':[0, 1, 5],
'B':[pd.Timestamp('20200101'), '20190203', '20190403']})
print(df)
print('Chèn missing data vào vị trí đầu của cột 1 và vị trí thứ 2 của cột 2')
df['A'].loc[0] = None
df['B'].loc[1] = np.nan
print(df)
|
Output:
Series không có missing value
0 1
1 2
2 4
dtype: int64
0 NaN
1 2.0
2 4.0
dtype: float64
Tạo DataFrame không có missing value
A B
0 0 2020-01-01
1 1 2019-02-03
2 5 2019-04-03
Chèn missing data vào vị trí đầu của cột 1 và vị trí thứ 2 của cột 2
A B
0 NaN 2020-01-01
1 1.0 NaT
2 5.0 2019-04-03
|
Hybrid Technologies đã trình bày về các thao tác với Mising Data hay sử dụng trong Pandas. Hy vọng bài viết sẽ giúp ích cho các bạn trong công việc. Hãy để lời góp ý trong phần bình luận bên dưới nhé và hẹn gặp lại trong các bài viết tiếp theo!
Tham khảo
1. http://pandas.pydata.org/pandas-docs/stable/user_guide/missing_data.html
2. https://pandas.pydata.org/pandas-docs/stable/user_guide/cookbook.html#cookbook-missing-data