Menu
CoddyTech

Cheat sheet pandas

Cập nhật lần cuối

Tạo DataFrame

DataFrame nhỏ tạo bằng tay, dùng cho ví dụ, kiểm thử và bảng tra cứu.

Việc cần làmCode
Import pandas và NumPyimport pandas as pd import numpy as np
Từ dict các cộtdf = pd.DataFrame({"name": ["Ada", "Ben"], "age": [36, 28]})
Từ danh sách các hàngpd.DataFrame([{"name": "Ada", "age": 36}, {"name": "Ben", "age": 28}])
Từ mảng NumPypd.DataFrame(np.arange(6).reshape(3, 2), columns=["x", "y"])
Series có nhãns = pd.Series([3, 5, 2], index=["a", "b", "c"])
Một dãy ngàypd.date_range("2026-01-01", periods=7, freq="D")

Đọc và ghi tệp

Một lệnh nạp tệp vào DataFrame, một lệnh ghi lại ra tệp.

Việc cần làmCode
Đọc tệp CSVdf = pd.read_csv("sales.csv")
Chỉ lấy vài cột, đọc đúng kiểu ngàypd.read_csv("sales.csv", usecols=["date", "city", "sales"], parse_dates=["date"])
Dùng một cột làm indexpd.read_csv("sales.csv", index_col="id")
Phân tách bằng tab hoặc ký tự khácpd.read_csv("sales.tsv", sep="\t")
Coi thêm một số ký hiệu là giá trị thiếupd.read_csv("sales.csv", na_values=["n/a", "-"])
Chỉ đọc những hàng đầupd.read_csv("sales.csv", nrows=1000)
Đọc một sheet Excel (cần openpyxl)pd.read_excel("report.xlsx", sheet_name="2026")
Đọc bản ghi JSONpd.read_json("records.json")
Đọc từ cơ sở dữ liệu SQLpd.read_sql("SELECT * FROM orders", conn)
Ghi CSV không kèm indexdf.to_csv("clean.csv", index=False)
Ghi Excel hoặc Parquetdf.to_excel("clean.xlsx", index=False), df.to_parquet("clean.parquet")

Xem dữ liệu

Những lệnh đầu tiên nên chạy với mọi tập dữ liệu mới.

Việc cần làmCode
Những hàng đầu và cuốidf.head(), df.tail(3)
Số hàng và số cộtdf.shape # (6, 7)
Kiểu của cột và số giá trị khác nulldf.info()
Thống kê tóm tắt các cột sốdf.describe()
Tóm tắt mọi cộtdf.describe(include="all")
Tên và kiểu của các cộtdf.columns, df.dtypes
Đếm từng giá trịdf["city"].value_counts()
Tỷ lệ của từng giá trịdf["city"].value_counts(normalize=True)
Các giá trị khác nhau và số lượngdf["city"].unique(), df["city"].nunique()
Số giá trị thiếu mỗi cộtdf.isna().sum()
Lấy mẫu ngẫu nhiên các hàngdf.sample(3, random_state=0)
Tương quan giữa các cột sốdf.corr(numeric_only=True)

Chọn cột và hàng

loc chọn theo nhãn và lấy cả điểm cuối của slice. iloc chọn theo vị trí và bỏ điểm cuối.

Việc cần làmCode
Một cột, dạng Seriesdf["age"]
Nhiều cột, dạng DataFramedf[["name", "age"]]
Hàng và cột theo nhãndf.loc[0:2, ["name", "age"]]
Hàng và cột theo vị trídf.iloc[0:2, 0:3]
Một giá trịdf.at[0, "age"], df.iat[0, 3]
Hàng cuốidf.iloc[-1]
Các cột thuộc một kiểudf.select_dtypes(include="number")
Các cột văn bản (pandas 3)df.select_dtypes(include="str")
Các cột có tên khớp mẫudf.filter(like="sal"), df.filter(regex="^(age|salary)$")
Tra cứu hàng theo một cộtdf.set_index("name").loc["Ada", "salary"]
Đưa về index 0, 1, 2df.reset_index(drop=True)
Xóa cột hoặc hàngdf.drop(columns=["email"]), df.drop(index=[0, 1])

Lọc hàng

Đặt mỗi điều kiện trong ngoặc đơn và kết hợp bằng & (và), | (hoặc) và ~ (phủ định).

Việc cần làmCode
Các hàng thỏa điều kiệndf[df["age"] > 30]
Cả hai điều kiệndf[(df["age"] > 30) & (df["city"] == "Oslo")]
Một trong hai điều kiệndf[(df["city"] == "Oslo") | (df["salary"] > 6000)]
Giá trị nằm trong danh sáchdf[df["city"].isin(["Oslo", "Rome"])]
Giá trị không nằm trong danh sáchdf[~df["city"].isin(["Oslo", "Rome"])]
Nằm giữa hai giá trị, tính cả hai đầudf[df["age"].between(30, 40)]
Lọc bằng chuỗi querydf.query("age > 30 and city == 'Oslo'")
Dùng biến trong querymin_age = 30 df.query("age > @min_age")
Văn bản chứadf[df["name"].str.contains("e", case=False)]
Giá trị thiếu hoặc có giá trịdf[df["age"].isna()], df[df["age"].notna()]
Lọc hàng và chọn cộtdf.loc[df["age"] > 30, ["name", "salary"]]
n hàng lớn nhất hoặc nhỏ nhấtdf.nlargest(3, "salary"), df.nsmallest(2, "age")
Các hàng có giá trị lặp lạidf[df.duplicated(subset=["city"], keep=False)]

Sắp xếp và xếp hạng

Việc cần làmCode
Sắp xếp theo một cộtdf.sort_values("salary")
Lớn nhất trướcdf.sort_values("salary", ascending=False)
Sắp xếp theo nhiều cộtdf.sort_values(["city", "salary"], ascending=[True, False])
Giá trị thiếu lên đầudf.sort_values("age", na_position="first")
Sắp xếp theo indexdf.sort_index()
Xếp hạng giá trị, 1 là cao nhấtdf["salary"].rank(ascending=False)

Thêm và thay đổi cột

Phép toán trên cả cột chạy rất nhanh. Chỉ dùng apply khi không có phương thức sẵn nào làm được việc đó.

Việc cần làmCode
Cột mới tính từ các cột khácdf["bonus"] = df["salary"] * 0.1
Thêm cột ngay trong chuỗi lệnhdf.assign(bonus=lambda d: d["salary"] * 0.1)
Giá trị theo một điều kiệndf["level"] = np.where(df["age"] >= 40, "senior", "junior")
Giá trị theo nhiều điều kiệndf["band"] = np.select([df["age"] < 30, df["age"] < 45], ["young", "mid"], default="senior")
Đổi giá trị ở chỗ thỏa điều kiệndf.loc[df["city"] == "Lima", "salary"] = 4000
Ánh xạ giá trị bằng dictdf["country"] = df["city"].map({"Oslo": "NO", "Rome": "IT", "Lima": "PE"})
Áp dụng hàm cho một cộtdf["salary"].apply(lambda x: round(x, -3))
Áp dụng hàm cho từng ôdf[["age", "salary"]].map(lambda x: x / 1000)
Đổi tên cộtdf.rename(columns={"salary": "pay"})
Đổi kiểu của cộtdf["salary"].astype("float64")
Văn bản thành số, giá trị lỗi thành NaNpd.to_numeric(s, errors="coerce")
Chia số vào các khoảng có nhãnpd.cut(df["age"], bins=[0, 30, 45, 120], labels=["young", "mid", "senior"])
Chia số thành các nhóm bằng nhaupd.qcut(df["salary"], q=4, labels=False)
Lặp qua các hàng (chậm, chỉ dùng khi hết cách)for row in df.itertuples(): print(row.name, row.salary)

Giá trị thiếu và làm sạch

Số bị thiếu hiển thị là NaN, ngày bị thiếu là NaT. Mỗi lệnh dưới đây trả về một đối tượng mới, nên hãy gán lại kết quả.

Việc cần làmCode
Tỷ lệ giá trị thiếu mỗi cộtdf.isna().mean()
Xóa hàng có bất kỳ giá trị thiếu nàodf.dropna()
Xóa hàng thiếu một cột quan trọngdf.dropna(subset=["age"])
Điền giá trị riêng cho từng cộtdf.fillna({"age": df["age"].median()})
Điền từ hàng trước hoặc hàng saudf["age"].ffill(), df["age"].bfill()
Điền chỗ trống bằng nội suydf["age"].interpolate()
Biến các ký hiệu thành giá trị thiếudf.replace(["n/a", "-", ""], np.nan)
Xóa hàng trùng lặpdf.drop_duplicates()
Giữ hàng cuối cùng của mỗi khóadf.drop_duplicates(subset=["city"], keep="last")
Chuẩn hóa tên cộtdf.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
Giới hạn giá trị cực đoandf["salary"].clip(lower=4000, upper=6000)
Kiểu category cho văn bản lặp lạidf["city"] = df["city"].astype("category")

Cột văn bản (.str)

Trong pandas 3, cột văn bản mặc định có dtype str. Các phương thức .str chạy trên cả cột, và giá trị thiếu vẫn giữ nguyên là thiếu.

Việc cần làmCode
Chữ hoa, chữ thường hoặc viết hoa đầu từdf["name"].str.upper(), df["name"].str.lower(), df["name"].str.title()
Cắt khoảng trắngdf["name"].str.strip()
Thay thế văn bảndf["email"].str.replace("mail.com", "example.com")
Thay thế bằng regexdf["email"].str.replace(r"@.*", "", regex=True)
Chứa, bắt đầu bằngdf["name"].str.contains("a"), df["name"].str.startswith("E")
Độ dài mỗi giá trịdf["name"].str.len()
Những ký tự đầudf["name"].str[:2]
Tách thành nhiều cộtdf["email"].str.split("@", expand=True)
Trích xuất bằng nhóm regexdf["email"].str.extract(r"@(\w+)")
Nối các cột văn bảndf["name"] + " (" + df["city"] + ")"
Thêm số 0 vào trước sốdf["salary"].astype("str").str.zfill(6)
Dtype văn bản mớidf["name"].dtype # str

Ngày và giờ

Accessor .dt dùng cho cột datetime. Một index ngày đã sắp xếp (ts bên dưới) cho phép slice bằng văn bản và resample.

Việc cần làmCode
Chuyển một cột thành datetimedf["date"] = pd.to_datetime(df["date"])
Chuyển với định dạng chính xácpd.to_datetime(["03/01/2026", "15/01/2026"], format="%d/%m/%Y")
Năm, tháng, tên thứ trong tuầndf["date"].dt.year, df["date"].dt.month, df["date"].dt.day_name()
Nhóm ngày theo thángdf["date"].dt.to_period("M")
Số ngày giữa hai ngày(pd.Timestamp("2026-12-31") - df["date"]).dt.days
Cộng thêm ngày hoặc thángdf["date"] + pd.Timedelta(days=30), df["date"] + pd.DateOffset(months=1)
Các hàng trong một khoảng ngàydf[df["date"].between("2021-01-01", "2022-12-31")]
Index ngày, slice bằng văn bảnts = df.set_index("date").sort_index() ts.loc["2021":"2022"]
Tổng theo thángts["salary"].resample("ME").sum()
Trung bình theo tuần; "QE" là theo quý, "YE" theo nămts["salary"].resample("W").mean()
Trung bình trượtts["salary"].rolling(3).mean()
Thay đổi so với hàng trướcts["salary"].diff(), ts["salary"].pct_change()
Dời giá trị xuống một hàngts["salary"].shift(1)
Tổng lũy kếts["salary"].cumsum()
Đặt và chuyển múi giờts.index.tz_localize("UTC").tz_convert("Europe/Oslo")

Nhóm và tổng hợp

groupby chia các hàng theo khóa, áp dụng một hàm cho từng nhóm rồi gộp kết quả lại.

Việc cần làmCode
Trung bình mỗi nhómdf.groupby("city")["salary"].mean()
Nhiều thống kê cùng lúcdf.groupby("city")["salary"].agg(["mean", "max", "count"])
Đặt tên cho cột kết quảdf.groupby("city").agg(avg_pay=("salary", "mean"), people=("name", "count"))
Nhóm theo hai cộtdf.groupby(["city", "team"])["salary"].sum()
Giữ khóa ở dạng cộtdf.groupby("city", as_index=False)["salary"].mean()
Số hàng mỗi nhómdf.groupby("city").size()
Kết quả của nhóm trên từng hàngdf["city_avg"] = df.groupby("city")["salary"].transform("mean")
Chỉ giữ một số nhómdf.groupby("city").filter(lambda g: len(g) >= 2)
Hàng có giá trị lớn nhất mỗi nhómdf.loc[df.groupby("city")["salary"].idxmax()]
n hàng đầu mỗi nhómdf.sort_values("salary", ascending=False).groupby("city").head(2)
Đánh số các hàng trong mỗi nhómdf.groupby("city").cumcount()
Lặp qua các nhómfor city, group in df.groupby("city"): print(city, len(group))
Lọc, nhóm và sắp xếp trong một chuỗi lệnh(df.query("age > 30") .groupby("city", as_index=False) .agg(avg_pay=("salary", "mean")) .sort_values("avg_pay", ascending=False))

Pivot và reshape

Dữ liệu dạng dài có một hàng cho mỗi quan sát. Dữ liệu dạng rộng trải một biến ra nhiều cột.

Việc cần làmCode
Pivot tabledf.pivot_table(index="city", columns="team", values="salary", aggfunc="mean", fill_value=0)
Bảng pivot có dòng tổngdf.pivot_table(index="city", values="salary", aggfunc="sum", margins=True)
Đếm các tổ hợppd.crosstab(df["city"], df["team"])
Tỷ lệ theo từng hàngpd.crosstab(df["city"], df["team"], normalize="index")
Từ rộng sang dàilong = df.melt(id_vars="name", value_vars=["age", "salary"], var_name="field", value_name="value")
Từ dài sang rộnglong.pivot(index="name", columns="field", values="value")
Đưa cấp index trong cùng thành cộtdf.groupby(["city", "team"])["salary"].sum().unstack(fill_value=0)
Mỗi phần tử của list một hàngpd.DataFrame({"id": [1, 2], "tags": [["a", "b"], ["c"]]}).explode("tags")
Mã hóa one-hot một cộtpd.get_dummies(df["team"], prefix="team")
Hoán đổi hàng và cộtdf.T

Kết hợp DataFrame

concat xếp chồng các DataFrame, merge nối chúng theo cột khóa giống cách SQL làm.

Việc cần làmCode
Xếp chồng hàngpd.concat([df_2025, df_2026], ignore_index=True)
Đặt cạnh nhaupd.concat([left, right], axis=1)
Nối theo một cột khóaorders.merge(customers, on="customer_id", how="left")
Các kiểu nốihow="inner", "left", "right", "outer"
Khóa có tên khác nhauorders.merge(users, left_on="customer_id", right_on="id")
Kiểm tra phép nối và đánh dấu nguồn của từng hàngorders.merge(customers, on="customer_id", how="left", validate="many_to_one", indicator=True)
Nối theo indexleft.join(right, how="inner")
Các hàng không khớp với bảng khácorders[~orders["customer_id"].isin(customers["customer_id"])]

Vẽ biểu đồ với pandas

pandas vẽ bằng Matplotlib. Mỗi lệnh vẽ trả về một ax của Matplotlib, nên bạn có thể tiếp tục tùy chỉnh.

Việc cần làmCode
Biểu đồ đường của một seriests["salary"].plot()
Biểu đồ đường từ hai cộtdf.plot(x="date", y="salary")
Biểu đồ cột của bảng tóm tắtdf.groupby("city")["salary"].mean().plot.bar()
Thanh ngang đã sắp xếpdf["city"].value_counts().sort_values().plot.barh()
Histogramdf["salary"].plot.hist(bins=20)
Scatter plotdf.plot.scatter(x="age", y="salary")
Biểu đồ hộp theo nhómdf.boxplot(column="salary", by="city")
Tiêu đề và nhãn trụcax = df.plot(x="date", y="salary", title="Salary") ax.set_ylabel("EUR")
Hiển thị hoặc lưu biểu đồplt.show(), ax.figure.savefig("salary.png", dpi=150)

pandas 3: cách viết cũ và cách viết bây giờ

Code chép từ các hướng dẫn cũ thường lỗi hoặc báo cảnh báo trong pandas 3. Hãy viết theo cột pandas 3.

Việc cần làmpandas 3Cách viết cũ
Hàm trên từng ôdf.map(f)df.applymap(f)
Điền từ hàng trướcdf.ffill()df.fillna(method="ffill")
Thêm hàngpd.concat([df, new_rows])df.append(new_rows)
Resample theo cuối thángts["salary"].resample("ME").sum()resample("M")
Ngày theo từng giờpd.date_range("2026-01-01", periods=24, freq="h")freq="H"
Gán một giá trịdf.loc[0, "age"] = 37df["age"][0] = 37
Thay đổi một phần đã lọchigh = df[df["salary"] > 5000] high["salary"] = 0high = df[df["salary"] > 5000].copy()
Đây có phải cột văn bản không?df["name"].dtype == "str"df["name"].dtype == object

Những đoạn code pandas mà một người phân tích dữ liệu dùng hằng ngày, xếp theo việc cần làm: tạo và nạp dữ liệu, xem dữ liệu, chọn và lọc hàng, thêm cột, xử lý giá trị thiếu, làm việc với văn bản và ngày tháng, nhóm và tổng hợp, reshape, merge và vẽ biểu đồ. Mỗi hàng là một đoạn code ngắn để bạn dán vào, kèm một dòng giải thích nó làm gì.

Mọi thứ ở đây viết cho pandas 3, phiên bản Coddy đang chạy: cột văn bản dùng dtype str mới, Copy-on-Write luôn bật, và các API đã bị gỡ như applymap và fillna(method=...) chỉ xuất hiện trong bảng cách viết cũ. Các ví dụ dùng một DataFrame df với các cột name, city, team, age, salary, date và email. Mới làm quen với Python? Hãy bắt đầu với cheat sheet Python và Python playground, rồi giữ các cheat sheet NumPy, Matplotlib và scikit-learn bên cạnh trang này.

Câu hỏi thường gặp về cheat sheet pandas

Cheat sheet pandas này có miễn phí không?

Có. Cheat sheet pandas này hoàn toàn miễn phí, không cần đăng ký. Bạn có thể lưu dấu trang hoặc in ra PDF từ trình duyệt, rồi quay lại bất cứ lúc nào cần đúng lệnh cho groupby, merge hay bảng pivot.

Cheat sheet này dùng pandas phiên bản nào?
pandas 3. Cột văn bản dùng dtype str mới, Copy-on-Write luôn bật, và các lệnh đã bị gỡ trong pandas 3 (applymap, fillna(method=...), append, các bí danh tần suất M và H) chỉ xuất hiện trong bảng cuối, cạnh cách viết thay thế. Hầu hết các đoạn code cũng chạy được trên pandas 2.2, trừ những hàng dựa vào dtype str hoặc Copy-on-Write.
loc và iloc khác nhau thế nào?
loc chọn theo nhãn: giá trị index và tên cột, và một slice như df.loc[0:2] lấy cả điểm cuối. iloc chọn theo vị trí số nguyên, giống list trong Python, nên df.iloc[0:2] trả về hai hàng đầu và bỏ điểm cuối. Dùng loc với một điều kiện để vừa lọc hàng vừa chọn cột trong một bước: df.loc[df["age"] > 30, ["name"]].
Làm sao lọc DataFrame theo nhiều điều kiện?
Đặt mỗi điều kiện trong ngoặc đơn và nối chúng bằng & cho và, | cho hoặc, ~ cho phủ định: df[(df["age"] > 30) & (df["city"] == "Oslo")]. Từ khóa and và or của Python không dùng được trên cả cột. Với bộ lọc dài, df.query("age > 30 and city == 'Oslo'") dễ đọc hơn.
merge, join và concat khác nhau thế nào?
merge kết hợp hai DataFrame theo cột khóa, giống phép join trong SQL, với how="inner", "left", "right" hoặc "outer". join là cách viết tắt để merge theo index. concat hoàn toàn không so khớp khóa: nó xếp chồng các DataFrame lên nhau, hoặc đặt cạnh nhau với axis=1.
Vì sao phép gán không làm thay đổi DataFrame?
Từ pandas 3, Copy-on-Write khiến mọi phép chọn đều hoạt động như một bản sao. Phép gán nối chuỗi như df["age"][0] = 37 chỉ thay đổi một đối tượng tạm và không đụng tới df. Hãy viết thành một lệnh loc: df.loc[0, "age"] = 37. Các phương thức như dropna và fillna cũng trả về đối tượng mới, nên hãy gán lại kết quả.
Có thể chạy code pandas online không?
Có. Matplotlib playground miễn phí chạy Python cùng pandas, NumPy, Matplotlib và scikit-learn ngay trong trình duyệt, nên bạn có thể dán bất kỳ đoạn code nào từ cheat sheet này và chạy mà không cần cài đặt gì. Khóa học Machine Learning của Coddy dạy pandas từng bước, từ DataFrame đầu tiên đến dữ liệu dùng để huấn luyện mô hình.
Hình minh họa các ngôn ngữ lập trình của Coddy

Học Pandas cùng Coddy

Bắt đầu