📊 PHẦN 6: PHÂN TÍCH VÀ TRỰC QUAN HÓA DỮ LIỆU
🎯 Mục tiêu tổng quát
- Thành thạo môi trường làm việc Jupyter Notebook cho phân tích dữ liệu.
- Nắm vững cách sử dụng NumPy để thực hiện các phép toán trên mảng hiệu suất cao.
- Sử dụng Pandas để thực hiện các tác vụ phân tích dữ liệu từ đầu đến cuối: đọc, khám phá, làm sạch, biến đổi và tổng hợp dữ liệu.
- Sử dụng Matplotlib và Seaborn để tạo ra các biểu đồ trực quan, truyền tải thông tin hiệu quả.
- Hoàn thành một dự án phân tích dữ liệu nhỏ, trả lời các câu hỏi kinh doanh dựa trên một bộ dữ liệu thực tế.
🧑🏫 Bài 1: Môi trường làm việc và Giới thiệu NumPy
Jupyter Notebook: Sân chơi của nhà khoa học dữ liệu
Jupyter Notebook là một ứng dụng web cho phép bạn tạo và chia sẻ các tài liệu chứa code, phương trình, trực quan hóa và văn bản tường thuật.
Cực kỳ hữu ích cho việc khám phá dữ liệu tương tác vì bạn có thể chạy từng khối code (cell) và xem ngay kết quả.
Cài đặt:
bashpip install notebookKhởi động:
bashjupyter notebook
NumPy: Nền tảng tính toán khoa học
- NumPy (Numerical Python) là thư viện cốt lõi cho tính toán khoa học trong Python.
- Cung cấp đối tượng mảng đa chiều (
ndarray) mạnh mẽ, hiệu quả hơn nhiều so với List của Python cho các phép toán số học.
import numpy as np
# Tạo một mảng NumPy từ List
a = np.array([1, 2, 3, 4, 5])
print(f"Mảng a: {a}")
print(f"Kiểu dữ liệu: {a.dtype}")
# Phép toán trên toàn bộ mảng (vectorization) - rất nhanh!
b = a * 2
print(f"Mảng b = a * 2: {b}")
# Các hàm thống kê cơ bản
print(f"Trung bình: {np.mean(a)}")
print(f"Tổng: {np.sum(a)}")
print(f"Giá trị lớn nhất: {np.max(a)}")
# Mảng 2 chiều (ma trận)
matrix = np.array([[1, 2, 3], [4, 5, 6]])
print("Ma trận:\n", matrix)
print(f"Kích thước: {matrix.shape}") # (2, 3) -> 2 hàng, 3 cột🧑🏫 Bài 2: Phân tích Dữ liệu với Pandas - Phần 1
Giới thiệu Pandas: Series và DataFrame
- Series: Một mảng một chiều có nhãn (giống một cột trong bảng tính), với các chỉ số (index).
- DataFrame: Một cấu trúc dữ liệu hai chiều có nhãn (giống một bảng tính hoàn chỉnh), với các cột có thể có kiểu dữ liệu khác nhau. Đây là đối tượng chính bạn sẽ làm việc trong Pandas.
import pandas as pd
# Tạo một Series
s = pd.Series([10, 20, 30, 40], index=['a', 'b', 'c', 'd'])
print("Series:\n", s)
# Tạo một DataFrame từ Dictionary
data = {
'Tên': ['An', 'Bình', 'Chi', 'Dũng'],
'Tuổi': [22, 25, 21, 30],
'Thành phố': ['Hà Nội', 'TP.HCM', 'Đà Nẵng', 'Hà Nội']
}
df = pd.DataFrame(data)
print("\nDataFrame:\n", df)Đọc và Ghi dữ liệu (CSV, Excel)
# Giả sử có file 'sales.csv'
# df = pd.read_csv('sales.csv')
# Ghi DataFrame ra file CSV
# df.to_csv('output.csv', index=False) # index=False để không ghi cột chỉ sốKhám phá dữ liệu ban đầu
# Hiển thị 5 dòng đầu tiên
print("5 dòng đầu:\n", df.head())
# Hiển thị 5 dòng cuối cùng
print("\n5 dòng cuối:\n", df.tail())
# Xem thông tin tổng quan (kiểu dữ liệu, số lượng giá trị không null)
print("\nThông tin DataFrame:")
df.info()
# Xem các thống kê mô tả cơ bản cho các cột số
print("\nThống kê mô tả:\n", df.describe())🧑🏫 Bài 3: Phân tích Dữ liệu với Pandas - Phần 2
Lựa chọn và Lọc dữ liệu (Indexing & Slicing)
# Chọn một cột (trả về một Series)
ages = df['Tuổi']
print("Cột Tuổi:\n", ages)
# Chọn nhiều cột (trả về một DataFrame)
name_city = df[['Tên', 'Thành phố']]
print("\nCột Tên và Thành phố:\n", name_city)
# Lọc các hàng dựa trên điều kiện
# Lấy những người có tuổi lớn hơn 23
older_than_23 = df[df['Tuổi'] > 23]
print("\nNhững người trên 23 tuổi:\n", older_than_23)
# Lọc với nhiều điều kiện (& là AND, | là OR)
# Những người ở Hà Nội VÀ trên 25 tuổi
hanoi_older_25 = df[(df['Thành phố'] == 'Hà Nội') & (df['Tuổi'] > 25)]
print("\nNgười ở Hà Nội và trên 25 tuổi:\n", hanoi_older_25)Làm sạch dữ liệu (Handling Missing Values)
# Tạo một DataFrame có giá trị thiếu (NaN - Not a Number)
data_with_nan = {
'A': [1, 2, np.nan, 4],
'B': [5, np.nan, np.nan, 8],
'C': [10, 20, 30, 40]
}
df_nan = pd.DataFrame(data_with_nan)
print("DataFrame với NaN:\n", df_nan)
# Xóa các hàng có chứa NaN
print("\nXóa hàng có NaN:\n", df_nan.dropna())
# Thay thế NaN bằng một giá trị khác (ví dụ: trung bình của cột)
mean_B = df_nan['B'].mean()
print("\nĐiền NaN bằng giá trị trung bình:\n", df_nan.fillna(value={'B': mean_B}))Thao tác trên cột và thêm cột mới
# Thêm một cột mới
df['Năm sinh'] = 2024 - df['Tuổi']
print("\nDataFrame với cột Năm sinh:\n", df)
# Áp dụng một hàm lên một cột
def categorize_age(age):
if age < 25:
return 'Trẻ'
else:
return 'Lớn tuổi'
df['Nhóm tuổi'] = df['Tuổi'].apply(categorize_age)
print("\nDataFrame với cột Nhóm tuổi:\n", df)🧑🏫 Bài 4: Trực quan hóa Dữ liệu với Matplotlib và Seaborn
Matplotlib: Xây dựng biểu đồ từ gốc
import matplotlib.pyplot as plt
x = ['A', 'B', 'C', 'D']
y = [10, 25, 15, 30]
plt.figure(figsize=(8, 5)) # Thiết lập kích thước
plt.bar(x, y) # Vẽ biểu đồ cột
plt.title('Biểu đồ Cột Đơn giản')
plt.xlabel('Hạng mục')
plt.ylabel('Giá trị')
plt.show() # Hiển thị biểu đồSeaborn: Vẽ biểu đồ thống kê đẹp mắt
import seaborn as sns
# Seaborn có thể vẽ trực tiếp từ DataFrame của Pandas
plt.figure(figsize=(8, 5))
sns.barplot(x='Tên', y='Tuổi', data=df)
plt.title('Biểu đồ Tuổi của Mọi người')
plt.show()
# Biểu đồ phân tán (scatterplot) để xem mối quan hệ
# sns.scatterplot(x='col1', y='col2', data=real_df)🧑🏫 Bài 5: Phân tích nâng cao với Pandas
Gom nhóm dữ liệu (Grouping with groupby)
Đây là một trong những tính năng mạnh mẽ nhất của Pandas, tương tự GROUP BY trong SQL.
# Gom nhóm theo 'Thành phố' và tính tuổi trung bình cho mỗi thành phố
city_avg_age = df.groupby('Thành phố')['Tuổi'].mean()
print("Tuổi trung bình theo thành phố:\n", city_avg_age)
# Gom nhóm và tính nhiều thống kê cùng lúc
city_stats = df.groupby('Thành phố')['Tuổi'].agg(['mean', 'count', 'max'])
print("\nThống kê tuổi theo thành phố:\n", city_stats)Kết hợp các DataFrame (Merging, Joining, Concatenating)
pd.concat(): Nối các DataFrame theo chiều dọc hoặc ngang.pd.merge(): Kết hợp các DataFrame dựa trên các cột chung (giốngJOINtrong SQL).
# Ví dụ về merge
df1 = pd.DataFrame({'key': ['A', 'B', 'C'], 'value1': [1, 2, 3]})
df2 = pd.DataFrame({'key': ['A', 'B', 'D'], 'value2': [4, 5, 6]})
# Inner join
merged_inner = pd.merge(df1, df2, on='key', how='inner')
print("Inner Merge:\n", merged_inner)
# Left join
merged_left = pd.merge(df1, df2, on='key', how='left')
print("\nLeft Merge:\n", merged_left)🧪 BÀI TẬP LỚN CUỐI PHẦN: Phân tích Dữ liệu Bán lẻ
Mô tả bài toán
Bạn được cung cấp một bộ dữ liệu về các giao dịch bán hàng của một siêu thị trực tuyến. Nhiệm vụ của bạn là thực hiện phân tích khám phá dữ liệu (Exploratory Data Analysis - EDA) để tìm ra những hiểu biết (insights) có giá trị, giúp doanh nghiệp đưa ra quyết định tốt hơn.
(Gợi ý bộ dữ liệu: Online Retail Data Set từ UCI. Bạn có thể tải file Online Retail.xlsx về.)
Yêu cầu
Sử dụng Jupyter Notebook để thực hiện và trình bày toàn bộ quá trình phân tích.
Đọc và Khám phá Dữ liệu:
- Đọc file dữ liệu vào một DataFrame.
- Hiển thị thông tin cơ bản:
head(),info(),describe(). - Kiểm tra xem có bao nhiêu dữ liệu bị thiếu ở mỗi cột.
Làm sạch và Tiền xử lý Dữ liệu:
- Xóa các hàng có
CustomerIDbị thiếu (vì không thể phân tích theo khách hàng). - Chuyển cột
InvoiceDatesang kiểu dữ liệu datetime. - Tạo các cột mới để phân tích dễ hơn:
TotalPrice = Quantity * UnitPrice.Month,DayOfWeek,Hourtừ cộtInvoiceDate.
- Xóa các hàng có
Phân tích và Trả lời câu hỏi:
- Top 10 sản phẩm bán chạy nhất là gì? (dựa trên tổng số lượng
Quantity). - Top 10 khách hàng chi tiêu nhiều nhất là ai? (dựa trên tổng
TotalPrice). - Doanh thu thay đổi như thế nào theo từng tháng?
- Khách hàng thường mua sắm vào thời điểm nào trong ngày/trong tuần?
- Top 10 sản phẩm bán chạy nhất là gì? (dựa trên tổng số lượng
Trực quan hóa Dữ liệu:
- Vẽ biểu đồ cột cho Top 10 sản phẩm và Top 10 khách hàng.
- Vẽ biểu đồ đường thể hiện doanh thu theo tháng.
- Vẽ biểu đồ cột thể hiện số lượng đơn hàng theo giờ trong ngày.
Tổng kết: Viết một vài câu kết luận về những insight bạn tìm thấy được từ dữ liệu (ví dụ: "Tháng 11 có doanh thu cao nhất, có thể do chuẩn bị cho dịp lễ. Công ty nên đẩy mạnh marketing vào thời gian này.").
