Sơ lược về Phân tích Dữ liệu

10 minute read

Trước khi bắt đầu, các bạn có thể cài đặt Python và các packages phục vụ cho việc phân tích dữ liệu một cách dễ dàng thông qua Anaconda tại đây https://www.anaconda.com/products/distribution

Nạp và kiểm tra kiểu dữ liệu

Việc nạp dữ liệu vào khung dữ liệu được thực hiện bằng các lệnh như df = pd.read_csv (…) hoặc df = pd.read_stata (…). Chúng ta sẽ nạp dữ liệu về Chiến tranh giữa các vì sao:

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pathlib import Path


# Đặt hạt giống nhằm thuận tiện cho việc tái tạo dãy số ngẫu nhiên
np.random.seed(10)
# Cài đặt số dòng hiển thị tối đa
pd.set_option("display.max_rows", 6)
# Cài đặt plot
plt.style.use(
    "https://github.com/aeturrell/coding-for-economists/raw/main/plot_style.txt"
)

df = (pd.read_csv(
    "https://github.com/aeturrell/coding-for-economists/raw/main/data/starwars.csv",
    index_col=0,
    )
    .dropna(subset=["species"])
    )
# Kiểm tra thông tin về khung dữ liệu
df.info()
<class 'pandas.core.frame.DataFrame'>
Int64Index: 82 entries, 0 to 86
Data columns (total 8 columns):
 #   Column      Non-Null Count  Dtype  
---  ------      --------------  -----  
 0   name        82 non-null     object 
 1   height      77 non-null     float64
 2   mass        58 non-null     float64
 3   hair_color  77 non-null     object 
 4   eye_color   80 non-null     object 
 5   gender      79 non-null     object 
 6   homeworld   74 non-null     object 
 7   species     82 non-null     object 
dtypes: float64(2), object(6)
memory usage: 5.8+ KB

Hiển thị một vài dòng đầu tiên với head()

df.head()

name height mass hair_color eye_color gender homeworld species
0 Luke Skywalker 172.0 77.0 blond blue male Tatooine Human
1 C-3PO 167.0 75.0 NaN yellow NaN Tatooine Droid
2 R2-D2 96.0 32.0 NaN red NaN Naboo Droid
3 Darth Vader 202.0 136.0 none yellow male Tatooine Human
4 Leia Organa 150.0 49.0 brown brown female Alderaan Human

Lọc các dòng và cột theo điều kiện bằng cách sử dụng lệnh df.loc [điều kiện hoặc dòng, cột]

.loc là viết tắt của location (vị trí) và cho phép người dùng lọc (còn gọi là tập hợp con) một khung dữ liệu. .loc hoạt động giống như một chỉ số, vì vậy nó luôn đi kèm với dấu ngoặc vuông, ví dụ: df.loc […].

loc cần hai tham số đầu vào. Đầu tiên là danh sách tên của các dòng bạn muốn chọn hoặc một điều kiện (tức là giá trị logic, với 1= đúng, 0=sai, có cùng độ dài với khung dữ liệu) chọn các dòng nhất định. Hãy nhớ rằng, bạn có thể dễ dàng tạo một loạt các giá trị logic bằng cách kiểm tra một cột với một điều kiện, ví dụ: df [‘column1’] == ‘black’.

Tham số thứ hai bao gồm danh sách tên cột bạn muốn chọn. Trong cả hai trường hợp,: là viết tắt của “sử dụng tất cả các dòng” hoặc “sử dụng tất cả các cột”. Nếu bạn có (các) điều kiện hoặc (các) cột (nhưng không phải cả hai), bạn chỉ cần viết df [condition (s)] hoặc df [column (s)].

Dưới đây là một ví dụ với một điều kiện được tạo từ hai phép so sánh và danh sách các cột:

df.loc[(df["hair_color"] == "brown") & (df["eye_color"] == "blue"), ["name", "species"]]
name species
6 Beru Whitesun lars Human
12 Chewbacca Wookiee
17 Jek Tono Porkins Human
30 Qui-Gon Jinn Human
58 Cliegg Lars Human
77 Tarfful Wookiee

Sắp xếp dòng với lệnh .sort_values()

Sằp xếp theo thứ tự giảm dần bằng lệnh sort_values(columns, ascending=False)

df.sort_values(["height", "mass"])
name height mass hair_color eye_color gender homeworld species
18 Yoda 66.0 17.0 white brown male NaN Yoda's species
71 Ratts Tyerell 79.0 15.0 none NaN male Aleen Minor Aleena
28 Wicket Systri Warrick 88.0 20.0 brown brown male Endor Ewok
... ... ... ... ... ... ... ... ...
82 Rey NaN NaN brown hazel female NaN Human
83 Poe Dameron NaN NaN brown brown male NaN Human
84 BB8 NaN NaN none black none NaN Droid

82 rows × 8 columns

Chọn nhiều dòng hoặc cột

Có thể dùng lát cắt để chọn nhiều dòng hoặc cột theo tên bằng cách sử dụng .loc [tên dòng đầu : tên dòng cuối : bước nhảy, tên cột đầu :tên cột cuối : bước nhảy] hoặc theo vị trí bằng cách sử dụng .iloc [chỉ số dòng đầu : chỉ số dòng cuối : bước nhảy,chỉ số cột đầu : chỉ số cột cuối : bước nhảy].

Ví dụ 1, chọn mỗi dòng thứ 10 từ hàng thứ hai và các cột giữa “tên” và “giới tính”:

df.loc[2::10, "name":"gender"]
name height mass hair_color eye_color gender
2 R2-D2 96.0 32.0 NaN red NaN
12 Chewbacca 228.0 112.0 brown blue male
22 Bossk 190.0 113.0 none red male
... ... ... ... ... ... ...
54 Plo Koon 188.0 80.0 none black male
64 Bail Prestor Organa 191.0 NaN black brown male
75 Shaak Ti 178.0 57.0 none black female

8 rows × 6 columns

Lưu ý rằng với trường hợp này, loc chấp nhận số vì với tập dữ liệu này, tên dòng được định dạng số. Nếu tên dòng định dạng văn bản và ta muốn cắt các dòng theo vị trí chỉ số của chúng, ta sẽ phải sử dụng iloc.

Ví dụ 2, chọn 5 dòng đầu tiên và 2 cột cuối cùng theo vị trí chỉ số:

df.iloc[:5, -2:]

homeworld species
0 Tatooine Human
1 Tatooine Droid
2 Naboo Droid
3 Tatooine Human
4 Alderaan Human

Chọn ngẫu nhiên mẫu với lệnh .sample

.sample(n) chọn ngẫu nhiên n dòng, .sample (frac = 0,4) chọn 40% dữ liệu, replace = True chọn mẫu bằng thay thế

Lấy mẫu gồm 5 dòng:

df.sample(5)

name height mass hair_color eye_color gender homeworld species
3 Darth Vader 202.0 136.0 none yellow male Tatooine Human
44 Dud Bolt 94.0 45.0 none yellow male Vulpter Vulptereen
41 Darth Maul 175.0 80.0 none yellow male Dathomir Zabrak
38 Sebulba 112.0 40.0 none orange male Malastare Dug
26 Mon Mothma 150.0 NaN auburn blue female Chandrila Human

Đổi tên bằng .rename

Bạn có thể đổi tên tất cả các cột bằng lệnh df.rename (columns = str.lower) để đặt tất cả các cột ở dạng chữ thường. Ngoài ra, sử dụng từ điển để cho biết cột nào nên thay thế bằng tên gì:

df.rename(columns={"homeworld": "home_world"})
name height mass hair_color eye_color gender home_world species
0 Luke Skywalker 172.0 77.0 blond blue male Tatooine Human
1 C-3PO 167.0 75.0 NaN yellow NaN Tatooine Droid
2 R2-D2 96.0 32.0 NaN red NaN Naboo Droid
... ... ... ... ... ... ... ... ...
83 Poe Dameron NaN NaN brown brown male NaN Human
84 BB8 NaN NaN none black none NaN Droid
86 Padmé Amidala 165.0 45.0 brown brown female Naboo Human

82 rows × 8 columns

Thêm các cột mới với .assign hoặc assignment

Thông thường, bạn sẽ muốn tạo các cột mới dựa trên các cột hiện có.

Có hai cách để làm điều này. Hãy cùng xem cả hai với một ví dụ trong đó chúng tôi muốn tạo một cột chiều cao mới tính bằng mét, được gọi là “height_m:.

Cách đầu tiên, và được sử dụng phổ biến nhất, được gọi là phép gán giá trị và chỉ bao gồm việc nhập tên cột mới trong khung dữ liệu và đặt nó ở phía bên trái của biểu thức gán được tính dựa trên các cột khung dữ liệu hiện có ở phía bên phải . Ví dụ: df [‘height_m’] = df [‘height’] / 100.

Thứ hai là sử dụng phương thức gán trực tiếp trên khung dữ liệu. Trong trường hợp này, câu lệnh gán xuất hiện bên trong dấu ngoặc. Ví dụ, df.assign (height_m = df [“height”] / 100).

Hãy xem các ví dụ của cả hai phương pháp gán giá trị này.

Trước tiên, hãy sử dụng phương pháp đầu tiên:

df['height_m'] = df['height']/100
df.head()
name height mass hair_color eye_color gender homeworld species height_m
0 Luke Skywalker 172.0 77.0 blond blue male Tatooine Human 1.72
1 C-3PO 167.0 75.0 NaN yellow NaN Tatooine Droid 1.67
2 R2-D2 96.0 32.0 NaN red NaN Naboo Droid 0.96
3 Darth Vader 202.0 136.0 none yellow male Tatooine Human 2.02
4 Leia Organa 150.0 49.0 brown brown female Alderaan Human 1.50

Và bây giờ là hàm .assign

df = df.assign(height_m=df["height"] / 100)
df.head()
name height mass hair_color eye_color gender homeworld species height_m
0 Luke Skywalker 172.0 77.0 blond blue male Tatooine Human 1.72
1 C-3PO 167.0 75.0 NaN yellow NaN Tatooine Droid 1.67
2 R2-D2 96.0 32.0 NaN red NaN Naboo Droid 0.96
3 Darth Vader 202.0 136.0 none yellow male Tatooine Human 2.02
4 Leia Organa 150.0 49.0 brown brown female Alderaan Human 1.50

Cột mới tạo được đặt cuối cùng; tuy nhiên, chúng tôi muốn nó bên cạnh cột chiều cao bằng cách sắp xếp các cột (axis = 1) theo thứ tự bảng chữ cái:

(df.assign(height_m=df["height"] / 100).sort_index(axis=1))
eye_color gender hair_color height height_m homeworld mass name species
0 blue male blond 172.0 1.72 Tatooine 77.0 Luke Skywalker Human
1 yellow NaN NaN 167.0 1.67 Tatooine 75.0 C-3PO Droid
2 red NaN NaN 96.0 0.96 Naboo 32.0 R2-D2 Droid
... ... ... ... ... ... ... ... ... ...
83 brown male brown NaN NaN NaN NaN Poe Dameron Human
84 black none none NaN NaN NaN NaN BB8 Droid
86 brown female brown 165.0 1.65 Naboo 45.0 Padmé Amidala Human

82 rows × 9 columns

Để ghi đè các cột hiện có, chỉ cần sử dụng height = df [‘height’] / 100 với phương thức gán hoặc df [‘height’] = df [‘height’] / 100.

Mô tả các giá trị số với .describe ()

df.describe()
height mass height_m
count 77.000000 58.000000 77.000000
mean 175.103896 98.162069 1.751039
std 34.483629 170.810183 0.344836
... ... ... ...
50% 180.000000 79.000000 1.800000
75% 191.000000 84.750000 1.910000
max 264.000000 1358.000000 2.640000

8 rows × 3 columns

Nhóm các giá trị với .groupby()

df.groupby("species")[["height", "mass"]].mean()
height mass
species
Aleena 79.0 15.0
Besalisk 198.0 102.0
Cerean 198.0 82.0
... ... ...
Xexto 122.0 NaN
Yoda's species 66.0 17.0
Zabrak 173.0 80.0

37 rows × 2 columns

Thêm các cột đã biến đổi bằng cách sử dụng .transform ()

Thông thường, việc thêm một cột vào khung dữ liệu là kết quả của một bước trung gian giữa bước groupby() và tổng hợp. Ví dụ, trừ giá trị trung bình của nhóm. Transform thực hiện điều này và trả về một cột đã biến đổi có cùng hình dạng với khung dữ liệu ban đầu. Biến đổi bảo toàn chỉ số ban đầu. (Có những phương pháp khác, chẳng hạn như apply, trả về khung dữ liệu mới với các biến theo nhóm làm chỉ số mới.)

Dưới đây là một ví dụ về hàm transform được sử dụng để loại giá trị trung bình theo loài. Lưu ý rằng chúng ta sử dụng các hàm lambda ở đây. Các hàm lambda là một cách viết hàm nhanh chóng mà không cần đặt tên cho chúng, ví dụ: lambda x: x + 1 xác định một hàm thêm một vào x. Trong ví dụ dưới đây, x trong hàm lambda đảm nhận vai trò của khối lượng được nhóm theo loài.

df["mass_demean_species"] = df.groupby("species")["mass"].transform(lambda x: x - x.mean())
df.head()
name height mass hair_color eye_color gender homeworld species height_m mass_demean_species
0 Luke Skywalker 172.0 77.0 blond blue male Tatooine Human 1.72 -5.781818
1 C-3PO 167.0 75.0 NaN yellow NaN Tatooine Droid 1.67 5.250000
2 R2-D2 96.0 32.0 NaN red NaN Naboo Droid 0.96 -37.750000
3 Darth Vader 202.0 136.0 none yellow male Tatooine Human 2.02 53.218182
4 Leia Organa 150.0 49.0 brown brown female Alderaan Human 1.50 -33.781818

Lập biểu đồ nhanh với .plot.

Bao gồm biểu đồ phân tán biểu, diện tích, cột, hộp, mật độ, lục giác, histogram, kernel và đường.

df.plot.scatter("mass", "height", alpha=0.5);

image-center

df.plot.box("species");

image-center

df["height"].plot.kde(bw_method=0.3);

image-center

Xuất kết quả và thống kê mô tả

Ta có thể xuất kết quả sang tệp latex để tích hợp vào bài báo, bản trình bày hoặc áp phích. Giả sử chúng ta đã có một số thống kê mô tả trên khung dữ liệu:

table = df[["mass", "height"]].agg([np.mean, np.std])
table
mass height
mean 98.162069 175.103896
std 170.810183 34.483629

Ta có thể xuất tệp này sang nhiều định dạng, bao gồm chuỗi, html, xml, markdown, clipboard, Excel, v.v.

Đây là một ví dụ về việc xuất bảng gấu trúc của bạn sang bảng LaTeX:

print(table.to_latex(caption="A Table", label="tab:descriptive"))
\begin{table}
\centering
\caption{A Table}
\label{tab:descriptive}
\begin{tabular}{lrr}
\toprule
{} &        mass &      height \\
\midrule
mean &   98.162069 &  175.103896 \\
std  &  170.810183 &   34.483629 \\
\bottomrule
\end{tabular}
\end{table}

Việc ghi vào terminal không hữu ích cho việc hoàn thành bài báo hoặc báo cáo! Để xuất dưới dạng tệp, hãy sử dụng table.to_latex(‘file.tex’, …).

Comments