.. raw:: html .. raw:: html .. raw:: html .. _sec_pandas: Tiền xử lý dữ liệu ================== .. raw:: html Cho đến giờ chúng tôi đã đề cập tới rất nhiều kỹ thuật thao tác dữ liệu được lưu trong dạng ``ndarray``. Nhưng để áp dụng học sâu vào giải quyết các vấn đề thực tế, ta thường phải bắt đầu bằng việc xử lý dữ liệu thô, chứ không có luôn dữ liệu ngăn nắp được chuẩn bị sẵn trong định dạng ``ndarray``. Trong số các công cụ phân tích dữ liệu phổ biến của Python, gói ``pandas`` khá được ưa chuộng. Cũng như nhiều gói khác trong hệ sinh thái rộng lớn của Python, ‘pandas’ có thể được sử dụng kết hợp với định dạng ``ndarray``. Vì vậy, chúng ta sẽ đi nhanh qua các bước để tiền xử lý dữ liệu thô bằng ``pandas`` rồi đổi chúng sang dạng ``ndarray``. Nhiều kỹ thuật tiền xử lý dữ liệu khác sẽ được giới thiệu trong các chương sau. .. raw:: html Đọc tập dữ liệu --------------- .. raw:: html Để lấy ví dụ, ta bắt đầu bằng việc tạo một tập dữ liệu nhân tạo lưu trong file csv ``../data/house_tiny.csv`` (csv - *comma-separated values - giá trị tách nhau bằng dấu phẩy*). Dữ liệu lưu ở các định dạng khác cũng có thể được xử lý tương tự. Hàm ``mkdir_if_not_exist`` dưới đây để đảm bảo rằng thư mục ``../data`` tồn tại. Chú thích ``# Saved in the d2l package for later use`` (*Lưu lại trong gói d2l để dùng sau*) là kí hiệu đánh dấu các hàm, lớp hoặc các lệnh ``import`` được lưu trong gói ``d2l``, để sau này ta có thể trực tiếp gọi hàm ``d2l.mkdir_if_not_exist()``. .. code:: python import os # Saved in the d2l package for later use def mkdir_if_not_exist(path): if not isinstance(path, str): path = os.path.join(*path) if not os.path.exists(path): os.makedirs(path) .. raw:: html Sau đây ta ghi tệp dữ liệu vào file csv theo từng hàng một. .. code:: python data_file = '../data/house_tiny.csv' mkdir_if_not_exist('../data') with open(data_file, 'w') as f: f.write('NumRooms,Alley,Price\n') # Column names f.write('NA,Pave,127500\n') # Each row is a data point f.write('2,NA,106000\n') f.write('4,NA,178100\n') f.write('NA,NA,140000\n') .. raw:: html .. raw:: html .. raw:: html Để nạp tập dữ liệu thô từ tệp csv vừa được tạo ra, ta dùng gói thư viện ``pandas`` và gọi hàm ``read_csv``. Bộ dữ liệu này có :math:`4` hàng và :math:`3` cột, trong đó mỗi hàng biểu thị số phòng (“NumRooms”), kiểu lối đi (“Alley”), và giá (“Price”) của căn nhà. .. code:: python # If pandas is not installed, just uncomment the following line: # !pip install pandas import pandas as pd data = pd.read_csv(data_file) print(data) .. parsed-literal:: :class: output NumRooms Alley Price 0 NaN Pave 127500 1 2.0 NaN 106000 2 4.0 NaN 178100 3 NaN NaN 140000 .. raw:: html .. raw:: html .. raw:: html .. raw:: html Xử lý dữ liệu thiếu ------------------- .. raw:: html Để ý rằng giá trị “NaN” là các giá trị bị thiếu. Để xử lý dữ liệu thiếu, các cách thường được áp dụng là *quy buộc* (*imputation*) và *xoá bỏ* (*deletion*), trong đó quy buộc thay thế giá trị bị thiếu bằng giá trị khác, trong khi xoá bỏ sẽ bỏ qua các giá trị bị thiếu. Dưới đây chúng ta xem xét phương pháp quy buộc. .. raw:: html Bằng phương pháp đánh chỉ số theo số nguyên (``iloc``), chúng ta tách ``data`` thành ``inputs`` (tương ứng với hai cột đầu) và ``outputs`` (tương ứng với cột cuối cùng). Với các giá trị số bị thiếu trong ``inputs``, ta thay thế phần tử “NaN” bằng giá trị trung bình cộng của cùng cột đó. .. code:: python inputs, outputs = data.iloc[:, 0:2], data.iloc[:, 2] inputs = inputs.fillna(inputs.mean()) print(inputs) .. parsed-literal:: :class: output NumRooms Alley 0 3.0 Pave 1 2.0 NaN 2 4.0 NaN 3 3.0 NaN .. raw:: html Với các giá trị dạng hạng mục hoặc số rời rạc trong ``inputs``, ta coi “NaN” là một mục riêng. Vì cột “Alley” chỉ nhận 2 giá trị riêng lẻ là “Pave” (được lát gạch) và “NaN”, ``pandas`` có thể tự động chuyển cột này thành 2 cột “Alley_Pave” và “Alley_nan”. Những hàng có kiểu lối đi là “Pave” sẽ có giá trị của cột “Alley_Pave” và cột “Alley_nan” tương ứng là :math:`1` và :math:`0`. Hàng mà không có giá trị cho kiểu lối đi sẽ có giá trị cột “Alley_Pave” và cột “Alley_nan” lần lượt là :math:`0` và :math:`1`. .. code:: python inputs = pd.get_dummies(inputs, dummy_na=True) print(inputs) .. parsed-literal:: :class: output NumRooms Alley_Pave Alley_nan 0 3.0 1 0 1 2.0 0 1 2 4.0 0 1 3 3.0 0 1 .. raw:: html .. raw:: html .. raw:: html Chuyển sang định dạng ``ndarray`` --------------------------------- .. raw:: html Giờ thì toàn bộ các giá trị trong ``inputs`` và ``outputs`` đã ở dạng số, chúng đã có thể được chuyển sang định dạng ``ndarray``. Khi đã ở định dạng này, chúng có thể được biến đổi và xử lý với những chức năng của ``ndarray`` đã được giới thiệu ở :numref:`sec_ndarray`. .. code:: python from mxnet import np X, y = np.array(inputs.values), np.array(outputs.values) X, y .. parsed-literal:: :class: output (array([[3., 1., 0.], [2., 0., 1.], [4., 0., 1.], [3., 0., 1.]], dtype=float64), array([127500, 106000, 178100, 140000], dtype=int64)) .. raw:: html Tóm tắt ------- .. raw:: html - Cũng như nhiều gói mở rộng trong hệ sinh thái khổng lồ của Python, ``pandas`` có thể làm việc được với ``ndarray``. - Phương pháp quy buộc hoặc xoá bỏ có thể dùng để xử lý dữ liệu bị thiếu. .. raw:: html Bài tập ------- .. raw:: html Tạo một tập dữ liệu với nhiều hàng và cột hơn. .. raw:: html 1. Xoá cột có nhiều giá trị bị thiếu nhất. 2. Chuyển bộ dữ liệu đã được xử lý sang định dạng ``ndarray``. .. raw:: html .. raw:: html .. raw:: html Thảo luận --------- - `Tiếng Anh `__ - `Tiếng Việt `__ .. raw:: html Những người thực hiện --------------------- Bản dịch trong trang này được thực hiện bởi: - Lê Khắc Hồng Phúc - Nguyễn Cảnh Thướng - Phạm Hồng Vinh - Đoàn Võ Duy Thanh - Vũ Hữu Tiệp - Mai Sơn Hải