יצירת מערכים
מערך מחזיק ערכים מסוג אחד ברשת עם כל מספר של ממדים.
| משימה | קוד |
|---|
| ייבוא NumPy | import numpy as np |
| מרשימה | np.array([1, 2, 3]) |
| מערך דו-ממדי מרשימות מקוננות | np.array([[1, 2, 3], [4, 5, 6]]) |
| אפסים, אחדות, ערך מילוי אחד | np.zeros((2, 3)), np.ones(4), np.full((2, 2), 7) |
| טווח עם צעד (בלי הקצה) | np.arange(0, 10, 2) # [0 2 4 6 8] |
| n נקודות במרווחים שווים (כולל הקצה) | np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1.] |
| מטריצת יחידה | np.eye(3) |
| באותו shape כמו מערך אחר | np.zeros_like(m), np.ones_like(m) |
| בחירת סוג האיברים | np.array([1, 2, 3], dtype=np.float32) |
| רשתות קואורדינטות | xx, yy = np.meshgrid(np.arange(3), np.arange(2)) |
בדיקת מערך
| משימה | קוד |
|---|
| Shape: הגודל של כל ממד | m.shape # (3, 4) |
| מספר הממדים | m.ndim # 2 |
| מספר האיברים | m.size # 12 |
| סוג האיברים | m.dtype # int64 |
| המרת הסוג | m.astype(np.float64) |
| האורך של הממד הראשון | len(m) # 3 |
| חזרה לרשימה של Python | m.tolist() |
| הדפסה עם פחות ספרות אחרי הנקודה | np.set_printoptions(precision=3, suppress=True) |
אינדקסים ו-slicing
Slices הם views: הם חולקים זיכרון עם המערך המקורי. מסכות ורשימות אינדקסים מחזירות עותקים.
| משימה | קוד |
|---|
| האיבר הראשון והאחרון | a[0], a[-1] |
| Slice start:stop (בלי stop) | a[1:4] # [20 30 40] |
| כל איבר שני, בסדר הפוך | a[::2], a[::-1] |
| איבר אחד במערך דו-ממדי | m[1, 2] # 6 |
| שורה, עמודה | m[0], m[:, 1] |
| בלוק של שורות ועמודות | m[:2, 1:3] |
| איברים שעומדים בתנאי | a[a > 25] # [30 40 50] |
| שילוב תנאים | a[(a > 15) & (a < 45)] |
| בחירה לפי רשימת מיקומים | a[[0, 2, 4]] |
| מיקומים שעומדים בתנאי | np.flatnonzero(a > 25) # [2 3 4] |
| בחירה לכל איבר | np.where(a > 25, a, 0) |
| העתקה לפני שינוי slice | part = a[1:3].copy() |
| השמת ערכים עם מסכה | a[a > 40] = 0 |
מתמטיקה ו-broadcasting
האופרטורים עובדים איבר-איבר. Broadcasting מותח סקלר, שורה או עמודה כדי שיתאימו ל-shape של המערך השני.
| משימה | קוד |
|---|
| אריתמטיקה איבר-איבר | x + y, x - y, x * y, x / y, x ** 2 |
| עם סקלר | x * 10 |
| שורש ריבועי, חזקה, לוגריתם | np.sqrt(x), np.exp(x), np.log(x) |
| ערך מוחלט, עיגול | np.abs(x - 5), np.round(x / 3, 2) |
| הגבלת ערכים לטווח | np.clip(x, 2, 8) |
| מקסימום איבר-איבר | np.maximum(x, 3) |
| מכפלה סקלרית | x @ y # 37.0 |
| מירכוז כל עמודה (broadcasting של שורה) | m - m.mean(axis=0) |
| שינוי סקאלה לכל שורה (broadcasting של עמודה) | m / m.sum(axis=1, keepdims=True) |
| השוואה בטוחה של floats | np.isclose(0.1 + 0.2, 0.3) # True, np.allclose(x, y) |
| טריגונומטריה ו-pi | np.sin(np.pi / 2) # 1.0 |
אגרגציה לאורך axis
axis=0 עובד לאורך השורות ונותן תוצאה אחת לכל עמודה. axis=1 עובד לרוחב העמודות ונותן תוצאה אחת לכל שורה.
| משימה | קוד |
|---|
| סכום כל האיברים | m.sum() # 21 |
| תוצאה אחת לכל עמודה | m.sum(axis=0) # [5 7 9] |
| תוצאה אחת לכל שורה | m.sum(axis=1) # [ 6 15] |
| ממוצע וסטיית תקן | m.mean(), m.std(), m.mean(axis=0) |
| מינימום, מקסימום | m.min(), m.max(axis=1) |
| המיקום של המקסימום | m.argmax(), m.argmax(axis=1) |
| חציון ואחוזונים | np.median(m), np.percentile(m, [25, 50, 75]) |
| סכום מצטבר | np.cumsum(m, axis=1) |
| מכפלת כל האיברים | m.prod() # 720 |
| Any, all, ספירה | (m > 4).any(), (m > 0).all(), np.count_nonzero(m > 2) |
Reshape ושילוב
Reshape שומר על האיברים ומשנה את ה-shape, ולכן הגודל הכולל חייב להישאר זהה.
| משימה | קוד |
|---|
| Shape חדש | a.reshape(2, 3) |
| לתת ל-NumPy לחשב גודל אחד | a.reshape(3, -1), a.reshape(-1, 1) |
| שיטוח למערך חד-ממדי | m.ravel(), m.flatten() |
| שחלוף (transpose) | m.T |
| הוספת ממד | a[:, np.newaxis], np.expand_dims(a, axis=0) |
| הסרת ממדים בגודל 1 | np.squeeze(np.ones((1, 3, 1))) |
| חיבור לאורך axis קיים | np.concatenate([a, a]) |
| הערמת שורות או עמודות | np.vstack([m, m]), np.hstack([m, m]) |
| מערכים חד-ממדיים כעמודות | np.column_stack([a, a ** 2]) |
| הערמה לאורך axis חדש | np.stack([a, a], axis=0) # shape (2, 6) |
| פיצול לחלקים | np.split(a, 3), np.array_split(a, 4) |
| חזרה או ריצוף | np.repeat([1, 2], 2) # [1 1 2 2], np.tile([1, 2], 2) # [1 2 1 2] |
מיון, חיפוש וערכים ייחודיים
| משימה | קוד |
|---|
| עותק ממוין | np.sort(a) |
| הגדול ביותר קודם | np.sort(a)[::-1] |
| המיקומים שימיינו את המערך | np.argsort(a) |
| שלושת הערכים הגדולים | np.sort(a)[-3:] |
| ערכים ייחודיים והספירות שלהם | values, counts = np.unique(a, return_counts=True) |
השמות של NumPy 2 (unique_values עשוי להחזיר לא ממוין) | np.unique_values(a), np.unique_counts(a) |
| האם כל איבר נמצא ברשימה? | np.isin(a, [1, 9]) |
| מיקום הכנסה במערך ממוין | np.searchsorted([1, 3, 5, 7], 4) # 2 |
| פעולות על קבוצות | np.intersect1d(a, [1, 2, 10]), np.union1d(a, [10]), np.setdiff1d(a, [1]) |
| מיון שורות לפי עמודה אחת | m[m[:, 1].argsort()] |
מספרים אקראיים
צרו Generator אחד עם seed ושלפו ממנו הכול, כך שהתוצאות יחזרו על עצמן בכל הרצה.
| משימה | קוד |
|---|
| Generator עם seed | rng = np.random.default_rng(42) |
| Floats בטווח [0, 1) | rng.random(3) |
| מספרים שלמים, בלי הקצה העליון | rng.integers(1, 7, size=10) |
| התפלגות נורמלית | rng.normal(loc=0, scale=1, size=(2, 3)) |
| Floats אחידים בטווח | rng.uniform(5, 10, size=4) |
| בחירה מרשימה | rng.choice(["a", "b", "c"], size=5) |
| בחירה בלי חזרות | rng.choice(10, size=3, replace=False) |
| בחירה עם משקלים | rng.choice(["H", "T"], size=10, p=[0.7, 0.3]) |
| עותק מעורבב, ערבוב במקום | rng.permutation(a), rng.shuffle(a) |
| ספירות בינומיות ופואסון | rng.binomial(10, 0.5, size=5), rng.poisson(3, size=5) |
אלגברה לינארית
| משימה | קוד |
|---|
| כפל מטריצות | A @ A |
| פתרון Ax = b | np.linalg.solve(A, b) # [0.8 1.4] |
| מטריצה הפוכה ודטרמיננטה | np.linalg.inv(A), np.linalg.det(A) |
| אורך וקטור | np.linalg.norm(b) |
| ערכים עצמיים ווקטורים עצמיים | values, vectors = np.linalg.eig(A) |
| התאמת קו ישר | slope, intercept = np.polyfit(x, y, 1) |
| מכפלה חיצונית | np.outer([1, 2], [3, 4]) |
| אלכסון ועקבה | np.diag(A), np.trace(A) |
ערכים חסרים ומיוחדים
np.nan מסמן float חסר. כל חישוב איתו נותן nan, אז השתמשו בפונקציות ה-nan או במסכה.
| משימה | קוד |
|---|
| ערך חסר | np.nan |
| מציאת ערכים חסרים | np.isnan(v), np.isnan(v).sum() |
| הסרת ערכים חסרים | v[~np.isnan(v)] |
| החלפת ערכים חסרים ואינסופיים | np.nan_to_num(v, nan=0.0, posinf=0.0) |
| בדיקות אינסוף וסופיות | np.inf, np.isfinite(v) |
| סטטיסטיקות שמדלגות על NaN | np.nanmean(v[:3]) # 2.0, np.nanmax(v) |
שמירה וטעינה
| משימה | קוד |
|---|
| מערך אחד, קובץ בינארי | np.save("data.npy", m), m = np.load("data.npy") |
| כמה מערכים בקובץ אחד | np.savez("data.npz", x=x, y=y), np.load("data.npz")["x"] |
| כתיבת CSV כטקסט | np.savetxt("data.csv", m, delimiter=",", fmt="%d") |
| קריאת CSV כטקסט | np.loadtxt("data.csv", delimiter=",") |
NumPy 2: שמות ישנים ומה לכתוב היום
NumPy 2 הסיר הרבה כינויים, ולכן קוד שהועתק ממדריכים ישנים עלול להיכשל עם AttributeError.
| משימה | NumPy 2 | צורה ישנה |
|---|
| ערך חסר | np.nan | np.NaN |
| אינסוף | np.inf | np.Inf |
| סוג float של 64 ביט | np.float64 | np.float_ |
| שטח מתחת לעקומה | np.trapezoid(y, x) | np.trapz(y, x) |
| האם כל איבר נמצא במערך אחר? | np.isin(a, b) | np.in1d(a, b) |
| הערמת שורות | np.vstack([a, a]) | np.row_stack([a, a]) |
| מכפלה | np.prod(a) | np.product(a) |
| מספרים אקראיים | rng = np.random.default_rng(0)
rng.random(3) | np.random.seed(0)
np.random.rand(3) |
הקריאות של NumPy שעליהן בנוי קוד ה-data science, מסודרות לפי משימה: יצירת מערכים, בדיקה שלהם, אינדקסים ו-slicing, מתמטיקה איבר-איבר, אגרגציה לאורך axis, reshape ושילוב, מיון וחיפוש, הגרלת מספרים אקראיים ופתרון בעיות באלגברה לינארית. כל שורה היא קטע קוד קצר שאפשר להדביק, ועוד שורה אחת שמסבירה מה הוא עושה.
הכול כאן כתוב ל-NumPy 2, הגרסה ש-Coddy מריץ, והטבלה האחרונה מציגה את השמות ש-NumPy 2 הסיר, לצד מה שצריך לכתוב במקומם. רוב הדוגמאות משתמשות ב-a = np.array([3, 1, 4, 1, 5, 9, 2, 6]) וב-m = np.arange(12).reshape(3, 4). חדשים ב-Python עצמו? התחילו עם Python cheat sheet ועם Python playground, ושמרו את דפי העזר של pandas, Matplotlib ו-scikit-learn לצד הדף הזה.