Pandas Cheat Sheet: דף עזר ל-pandas
עודכן לאחרונה
יצירת DataFrame
DataFrames קטנים שבונים ביד, לדוגמאות, לבדיקות ולטבלאות עזר.
| משימה | קוד |
|---|---|
| ייבוא pandas ו-NumPy | import pandas as pd
import numpy as np |
| ממילון של עמודות | df = pd.DataFrame({"name": ["Ada", "Ben"], "age": [36, 28]}) |
| מרשימה של שורות | pd.DataFrame([{"name": "Ada", "age": 36}, {"name": "Ben", "age": 28}]) |
| ממערך NumPy | pd.DataFrame(np.arange(6).reshape(3, 2), columns=["x", "y"]) |
| Series עם תוויות | s = pd.Series([3, 5, 2], index=["a", "b", "c"]) |
| טווח של תאריכים | pd.date_range("2026-01-01", periods=7, freq="D") |
קריאה וכתיבה של קבצים
קריאה אחת טוענת קובץ ל-DataFrame, וקריאה אחת כותבת אותו בחזרה.
| משימה | קוד |
|---|---|
| קריאת קובץ CSV | df = pd.read_csv("sales.csv") |
| רק חלק מהעמודות, עם תאריכים אמיתיים | pd.read_csv("sales.csv", usecols=["date", "city", "sales"], parse_dates=["date"]) |
| עמודה בתור index | pd.read_csv("sales.csv", index_col="id") |
| טאב או מפריד אחר | pd.read_csv("sales.tsv", sep="\t") |
| סימונים נוספים כערכים חסרים | pd.read_csv("sales.csv", na_values=["n/a", "-"]) |
| קריאת השורות הראשונות בלבד | pd.read_csv("sales.csv", nrows=1000) |
| קריאת גיליון Excel (דורש openpyxl) | pd.read_excel("report.xlsx", sheet_name="2026") |
| קריאת רשומות JSON | pd.read_json("records.json") |
| קריאה ממסד נתונים SQL | pd.read_sql("SELECT * FROM orders", conn) |
| כתיבת CSV בלי ה-index | df.to_csv("clean.csv", index=False) |
| כתיבה ל-Excel או Parquet | df.to_excel("clean.xlsx", index=False), df.to_parquet("clean.parquet") |
בדיקת הנתונים
הפקודות הראשונות שמריצים על כל dataset חדש.
| משימה | קוד |
|---|---|
| שורות ראשונות ואחרונות | df.head(), df.tail(3) |
| מספר שורות ועמודות | df.shape # (6, 7) |
| סוגי עמודות וספירת ערכים לא חסרים | df.info() |
| סטטיסטיקה תיאורית של עמודות מספריות | df.describe() |
| סיכום של כל העמודות | df.describe(include="all") |
| שמות וסוגי עמודות | df.columns, df.dtypes |
| ספירה של כל ערך | df["city"].value_counts() |
| השיעור של כל ערך | df["city"].value_counts(normalize=True) |
| ערכים ייחודיים וכמה יש | df["city"].unique(), df["city"].nunique() |
| ערכים חסרים בכל עמודה | df.isna().sum() |
| מדגם אקראי של שורות | df.sample(3, random_state=0) |
| קורלציה בין עמודות מספריות | df.corr(numeric_only=True) |
בחירת עמודות ושורות
loc בוחר לפי תווית וכולל את הקצה של ה-slice. iloc בוחר לפי מיקום ולא כולל אותו.
| משימה | קוד |
|---|---|
| עמודה אחת, כ-Series | df["age"] |
| כמה עמודות, כ-DataFrame | df[["name", "age"]] |
| שורות ועמודות לפי תווית | df.loc[0:2, ["name", "age"]] |
| שורות ועמודות לפי מיקום | df.iloc[0:2, 0:3] |
| ערך בודד | df.at[0, "age"], df.iat[0, 3] |
| השורה האחרונה | df.iloc[-1] |
| עמודות מסוג מסוים | df.select_dtypes(include="number") |
| עמודות טקסט (pandas 3) | df.select_dtypes(include="str") |
| עמודות לפי התאמת שם | df.filter(like="sal"), df.filter(regex="^(age|salary)$") |
| חיפוש שורות לפי עמודה | df.set_index("name").loc["Ada", "salary"] |
| חזרה ל-index של 0, 1, 2 | df.reset_index(drop=True) |
| מחיקת עמודות או שורות | df.drop(columns=["email"]), df.drop(index=[0, 1]) |
סינון שורות
עטפו כל תנאי בסוגריים וחברו אותם עם & (וגם), | (או) ו-~ (לא).
| משימה | קוד |
|---|---|
| שורות שעומדות בתנאי | df[df["age"] > 30] |
| שני התנאים | df[(df["age"] > 30) & (df["city"] == "Oslo")] |
| אחד מהתנאים | df[(df["city"] == "Oslo") | (df["salary"] > 6000)] |
| ערך מתוך רשימה | df[df["city"].isin(["Oslo", "Rome"])] |
| ערך שלא ברשימה | df[~df["city"].isin(["Oslo", "Rome"])] |
| בין שני ערכים, כולל הקצוות | df[df["age"].between(30, 40)] |
| סינון עם מחרוזת query | df.query("age > 30 and city == 'Oslo'") |
| משתנה בתוך query | min_age = 30
df.query("age > @min_age") |
| טקסט מכיל | df[df["name"].str.contains("e", case=False)] |
| ערכים חסרים או קיימים | df[df["age"].isna()], df[df["age"].notna()] |
| סינון שורות ובחירת עמודות | df.loc[df["age"] > 30, ["name", "salary"]] |
| n השורות העליונות או התחתונות | df.nlargest(3, "salary"), df.nsmallest(2, "age") |
| שורות עם ערך כפול | df[df.duplicated(subset=["city"], keep=False)] |
מיון ודירוג
| משימה | קוד |
|---|---|
| מיון לפי עמודה | df.sort_values("salary") |
| הגדול ביותר קודם | df.sort_values("salary", ascending=False) |
| מיון לפי כמה עמודות | df.sort_values(["city", "salary"], ascending=[True, False]) |
| ערכים חסרים קודם | df.sort_values("age", na_position="first") |
| מיון לפי ה-index | df.sort_index() |
| דירוג ערכים, 1 הוא הגבוה ביותר | df["salary"].rank(ascending=False) |
הוספה ושינוי של עמודות
פעולות על עמודה שלמה הן מהירות. השתמשו ב-apply רק כשאין מתודה מובנית שעושה את העבודה.
| משימה | קוד |
|---|---|
| עמודה חדשה מעמודות אחרות | df["bonus"] = df["salary"] * 0.1 |
| הוספת עמודה בתוך שרשרת | df.assign(bonus=lambda d: d["salary"] * 0.1) |
| ערך לפי תנאי | df["level"] = np.where(df["age"] >= 40, "senior", "junior") |
| ערך לפי כמה תנאים | df["band"] = np.select([df["age"] < 30, df["age"] < 45], ["young", "mid"], default="senior") |
| שינוי ערכים במקום שבו תנאי מתקיים | df.loc[df["city"] == "Lima", "salary"] = 4000 |
| מיפוי ערכים עם מילון | df["country"] = df["city"].map({"Oslo": "NO", "Rome": "IT", "Lima": "PE"}) |
| הפעלת פונקציה על עמודה | df["salary"].apply(lambda x: round(x, -3)) |
| הפעלת פונקציה על כל תא | df[["age", "salary"]].map(lambda x: x / 1000) |
| שינוי שמות עמודות | df.rename(columns={"salary": "pay"}) |
| שינוי סוג של עמודה | df["salary"].astype("float64") |
| טקסט למספרים, ערכים שגויים ל-NaN | pd.to_numeric(s, errors="coerce") |
| מספרים לטווחים עם תוויות | pd.cut(df["age"], bins=[0, 30, 45, 120], labels=["young", "mid", "senior"]) |
| מספרים לקבוצות שוות בגודלן | pd.qcut(df["salary"], q=4, labels=False) |
| לולאה על שורות (איטי, מוצא אחרון) | for row in df.itertuples():
print(row.name, row.salary) |
ערכים חסרים וניקוי
מספרים חסרים מוצגים כ-NaN, ותאריכים חסרים כ-NaT. כל אחת מהקריאות האלה מחזירה אובייקט חדש, אז שמרו את התוצאה במשתנה.
| משימה | קוד |
|---|---|
| שיעור הערכים החסרים בכל עמודה | df.isna().mean() |
| מחיקת שורות עם ערך חסר כלשהו | df.dropna() |
| מחיקת שורות שחסרה בהן עמודת מפתח | df.dropna(subset=["age"]) |
| מילוי בערך לכל עמודה | df.fillna({"age": df["age"].median()}) |
| מילוי מהשורה הקודמת או הבאה | df["age"].ffill(), df["age"].bfill() |
| מילוי חורים באינטרפולציה | df["age"].interpolate() |
| הפיכת סימונים לערכים חסרים | df.replace(["n/a", "-", ""], np.nan) |
| מחיקת שורות כפולות | df.drop_duplicates() |
| שמירת השורה האחרונה לכל מפתח | df.drop_duplicates(subset=["city"], keep="last") |
| סידור שמות העמודות | df.columns = df.columns.str.strip().str.lower().str.replace(" ", "_") |
| חיתוך ערכים קיצוניים | df["salary"].clip(lower=4000, upper=6000) |
| סוג category לטקסט שחוזר | df["city"] = df["city"].astype("category") |
עמודות טקסט (.str)
ב-pandas 3 עמודות טקסט מקבלות כברירת מחדל את ה-dtype str. מתודות ה-.str עובדות על העמודה כולה, וערכים חסרים נשארים חסרים.
| משימה | קוד |
|---|---|
| אותיות גדולות, קטנות או Title Case | df["name"].str.upper(), df["name"].str.lower(), df["name"].str.title() |
| הסרת רווחים | df["name"].str.strip() |
| החלפת טקסט | df["email"].str.replace("mail.com", "example.com") |
| החלפה עם regex | df["email"].str.replace(r"@.*", "", regex=True) |
| מכיל, מתחיל ב... | df["name"].str.contains("a"), df["name"].str.startswith("E") |
| האורך של כל ערך | df["name"].str.len() |
| התווים הראשונים | df["name"].str[:2] |
| פיצול לעמודות | df["email"].str.split("@", expand=True) |
| חילוץ עם קבוצת regex | df["email"].str.extract(r"@(\w+)") |
| חיבור עמודות טקסט | df["name"] + " (" + df["city"] + ")" |
| ריפוד מספרים באפסים | df["salary"].astype("str").str.zfill(6) |
| ה-dtype החדש לטקסט | df["name"].dtype # str |
תאריכים ושעות
ה-accessor .dt עובד על עמודות datetime. index ממוין של תאריכים (ts למטה) מאפשר slicing לפי טקסט ו-resampling.
| משימה | קוד |
|---|---|
| המרת עמודה ל-datetime | df["date"] = pd.to_datetime(df["date"]) |
| המרה עם פורמט מדויק | pd.to_datetime(["03/01/2026", "15/01/2026"], format="%d/%m/%Y") |
| שנה, חודש, שם היום בשבוע | df["date"].dt.year, df["date"].dt.month, df["date"].dt.day_name() |
| קיבוץ תאריכים לפי חודש | df["date"].dt.to_period("M") |
| מספר הימים בין שני תאריכים | (pd.Timestamp("2026-12-31") - df["date"]).dt.days |
| הוספת ימים או חודשים | df["date"] + pd.Timedelta(days=30), df["date"] + pd.DateOffset(months=1) |
| שורות בטווח תאריכים | df[df["date"].between("2021-01-01", "2022-12-31")] |
| index של תאריכים, slicing לפי טקסט | ts = df.set_index("date").sort_index()
ts.loc["2021":"2022"] |
| סכום לכל חודש | ts["salary"].resample("ME").sum() |
ממוצע שבועי; "QE" רבעוני, "YE" שנתי | ts["salary"].resample("W").mean() |
| ממוצע נע | ts["salary"].rolling(3).mean() |
| שינוי מהשורה הקודמת | ts["salary"].diff(), ts["salary"].pct_change() |
| הזזת ערכים שורה אחת למטה | ts["salary"].shift(1) |
| סכום מצטבר | ts["salary"].cumsum() |
| הגדרה והמרה של אזורי זמן | ts.index.tz_localize("UTC").tz_convert("Europe/Oslo") |
קיבוץ ואגרגציה
groupby מפצל את השורות לפי מפתח, מפעיל פונקציה על כל קבוצה ומאחד את התוצאות.
| משימה | קוד |
|---|---|
| ממוצע לכל קבוצה | df.groupby("city")["salary"].mean() |
| כמה סטטיסטיקות בבת אחת | df.groupby("city")["salary"].agg(["mean", "max", "count"]) |
| עמודות תוצאה עם שמות | df.groupby("city").agg(avg_pay=("salary", "mean"), people=("name", "count")) |
| קיבוץ לפי שתי עמודות | df.groupby(["city", "team"])["salary"].sum() |
| השארת המפתחות כעמודות | df.groupby("city", as_index=False)["salary"].mean() |
| מספר השורות בכל קבוצה | df.groupby("city").size() |
| תוצאת הקבוצה בכל שורה | df["city_avg"] = df.groupby("city")["salary"].transform("mean") |
| השארת חלק מהקבוצות בלבד | df.groupby("city").filter(lambda g: len(g) >= 2) |
| השורה עם המקסימום בכל קבוצה | df.loc[df.groupby("city")["salary"].idxmax()] |
| n השורות העליונות בכל קבוצה | df.sort_values("salary", ascending=False).groupby("city").head(2) |
| מספור השורות בכל קבוצה | df.groupby("city").cumcount() |
| לולאה על הקבוצות | for city, group in df.groupby("city"):
print(city, len(group)) |
| סינון, קיבוץ ומיון בשרשרת אחת | (df.query("age > 30")
.groupby("city", as_index=False)
.agg(avg_pay=("salary", "mean"))
.sort_values("avg_pay", ascending=False)) |
Pivot ו-reshape
בנתונים ארוכים יש שורה אחת לכל תצפית. בנתונים רחבים משתנה אחד פרוס על פני כמה עמודות.
| משימה | קוד |
|---|---|
| Pivot table | df.pivot_table(index="city", columns="team", values="salary", aggfunc="mean", fill_value=0) |
| Pivot table עם סיכומים | df.pivot_table(index="city", values="salary", aggfunc="sum", margins=True) |
| ספירת צירופים | pd.crosstab(df["city"], df["team"]) |
| שיעורים לכל שורה | pd.crosstab(df["city"], df["team"], normalize="index") |
| מרחב לארוך | long = df.melt(id_vars="name", value_vars=["age", "salary"], var_name="field", value_name="value") |
| מארוך לרחב | long.pivot(index="name", columns="field", values="value") |
| רמת index פנימית לעמודות | df.groupby(["city", "team"])["salary"].sum().unstack(fill_value=0) |
| שורה לכל פריט ברשימה | pd.DataFrame({"id": [1, 2], "tags": [["a", "b"], ["c"]]}).explode("tags") |
| One-hot encoding לעמודה | pd.get_dummies(df["team"], prefix="team") |
| החלפה בין שורות לעמודות | df.T |
שילוב DataFrames
concat מערים טבלאות זו על זו, ו-merge מצרף אותן לפי עמודות מפתח כמו ב-SQL.
| משימה | קוד |
|---|---|
| הערמת שורות | pd.concat([df_2025, df_2026], ignore_index=True) |
| הצבה זו לצד זו | pd.concat([left, right], axis=1) |
| צירוף לפי עמודת מפתח | orders.merge(customers, on="customer_id", how="left") |
| סוגי join | how="inner", "left", "right", "outer" |
| מפתחות עם שמות שונים | orders.merge(users, left_on="customer_id", right_on="id") |
| בדיקת ה-join וסימון המקור של כל שורה | orders.merge(customers, on="customer_id", how="left", validate="many_to_one", indicator=True) |
| צירוף לפי ה-index | left.join(right, how="inner") |
| שורות בלי התאמה בטבלה אחרת | orders[~orders["customer_id"].isin(customers["customer_id"])] |
גרפים עם pandas
pandas משרטט בעזרת Matplotlib. כל קריאת plot מחזירה ax של Matplotlib, כך שאפשר להמשיך לעצב אותו.
| משימה | קוד |
|---|---|
| גרף קווי של Series | ts["salary"].plot() |
| גרף קווי משתי עמודות | df.plot(x="date", y="salary") |
| גרף עמודות של סיכום | df.groupby("city")["salary"].mean().plot.bar() |
| עמודות אופקיות ממוינות | df["city"].value_counts().sort_values().plot.barh() |
| היסטוגרמה | df["salary"].plot.hist(bins=20) |
| גרף פיזור | df.plot.scatter(x="age", y="salary") |
| Box plot לכל קבוצה | df.boxplot(column="salary", by="city") |
| כותרת ותווית ציר | ax = df.plot(x="date", y="salary", title="Salary")
ax.set_ylabel("EUR") |
| הצגה או שמירה של הגרף | plt.show(), ax.figure.savefig("salary.png", dpi=150) |
pandas 3: צורות ישנות ומה לכתוב היום
קוד שהועתק ממדריכים ישנים נכשל או מציג אזהרות ב-pandas 3 לעיתים קרובות. כתבו במקום זאת את הצורות שבעמודת pandas 3.
| משימה | pandas 3 | צורה ישנה |
|---|---|---|
| פונקציה על כל תא | df.map(f) | df.applymap(f) |
| מילוי מהשורה הקודמת | df.ffill() | df.fillna(method="ffill") |
| הוספת שורות | pd.concat([df, new_rows]) | df.append(new_rows) |
| Resampling לסוף חודש | ts["salary"].resample("ME").sum() | resample("M") |
| תאריכים לפי שעה | pd.date_range("2026-01-01", periods=24, freq="h") | freq="H" |
| השמת ערך בודד | df.loc[0, "age"] = 37 | df["age"][0] = 37 |
| שינוי של תת-קבוצה מסוננת | high = df[df["salary"] > 5000]
high["salary"] = 0 | high = df[df["salary"] > 5000].copy() |
| האם זו עמודת טקסט? | df["name"].dtype == "str" | df["name"].dtype == object |
קוד ה-pandas שדאטה אנליסט משתמש בו כל יום, מסודר לפי משימה: יצירה וטעינה של נתונים, בדיקה שלהם, בחירה וסינון של שורות, הוספת עמודות, טיפול בערכים חסרים, עבודה עם טקסט ותאריכים, קיבוץ ואגרגציה, reshape, מיזוג ושרטוט. כל שורה היא קטע קוד קצר שאפשר להדביק, ועוד שורה אחת שמסבירה מה הוא עושה.
הכול כאן כתוב ל-pandas 3, הגרסה ש-Coddy מריץ: עמודות טקסט מקבלות את ה-dtype החדש str, Copy-on-Write תמיד פעיל, ו-APIs שהוסרו כמו applymap ו-fillna(method=...) מופיעים רק בטבלת הצורות הישנות. הדוגמאות משתמשות ב-DataFrame בשם df עם העמודות name, city, team, age, salary, date ו-email. חדשים ב-Python עצמו? התחילו עם Python cheat sheet ועם Python playground, ושמרו את דפי העזר של NumPy, Matplotlib ו-scikit-learn לצד הדף הזה.
שאלות נפוצות על ה-Pandas Cheat Sheet
האם ה-pandas cheat sheet הזה חינמי?
באיזו גרסה של pandas דף העזר הזה עוסק?
str, Copy-on-Write תמיד פעיל, וקריאות שהוסרו ב-pandas 3 (applymap, fillna(method=...), append, כינויי התדירות M ו-H) מופיעות רק בטבלה האחרונה, לצד מה שצריך לכתוב במקומן. כמעט כל קטע קוד רץ גם על pandas 2.2, חוץ מהשורות שמסתמכות על ה-dtype str או על Copy-on-Write.מה ההבדל בין loc ל-iloc?
loc בוחר לפי תווית: ערכי ה-index ושמות העמודות, ו-slice כמו df.loc[0:2] כולל את הקצה שלו. iloc בוחר לפי מיקום מספרי, כמו ברשימה של Python, ולכן df.iloc[0:2] מחזיר את שתי השורות הראשונות ולא כולל את הקצה. השתמשו ב-loc עם תנאי כדי לסנן שורות ולבחור עמודות בצעד אחד: df.loc[df["age"] > 30, ["name"]].איך מסננים DataFrame לפי כמה תנאים?
& עבור וגם, | עבור או, ו-~ עבור לא: df[(df["age"] > 30) & (df["city"] == "Oslo")]. ה-and וה-or של Python לא עובדים על עמודות שלמות. בסינונים ארוכים, df.query("age > 30 and city == 'Oslo'") קל יותר לקריאה.מה ההבדל בין merge, join ו-concat?
merge משלב שני DataFrames לפי עמודות מפתח, כמו join ב-SQL, עם how="inner", "left", "right" או "outer". join הוא קיצור דרך שמבצע merge לפי ה-index. concat לא מתאים מפתחות בכלל: הוא מערים טבלאות זו על זו, או זו לצד זו עם axis=1.למה ההשמה שלי לא משנה את ה-DataFrame?
df["age"][0] = 37 משנה אובייקט זמני ומשאירה את df בלי שינוי. כתבו אותה כקריאת loc אחת במקום: df.loc[0, "age"] = 37. גם מתודות כמו dropna ו-fillna מחזירות אובייקט חדש, אז שמרו את התוצאה במשתנה.