Sơ lược về Phân tích Dữ liệu
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);
df.plot.box("species");
df["height"].plot.kde(bw_method=0.3);
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