Smart-World Surf

יחידה 6: מבוא ל-NumPy

יסודות החישוב המספרי עם מערכים רב-ממדיים.
מערכי ndarrayפעולות וקטוריותאינדוקס ופריסהביצועים

ברוכים הבאים ליחידת הלימוד "מבוא ל-NumPy"! יחידה זו מהווה את אבן היסוד לחישובים נומריים וניתוח נתונים בפייתון. נלמד כיצד NumPy, באמצעות מבנה הנתונים המרכזי שלו – מערכי ndarray רב-ממדיים – מאפשר לבצע פעולות מתמטיות מורכבות ביעילות ובמהירות חסרות תקדים, תוך התגברות על מגבלות הביצועים של רשימות פייתון רגילות. הבנה מעמיקה של עקרונות אלו חיונית לכל מי שעוסק במדעי הנתונים, למידת מכונה וחישוב מדעי.

מערכי ndarray: עמוד השדרה של NumPy

הליבה של ספריית NumPy היא אובייקט ה-ndarray (N-dimensional array), שהוא מבנה נתונים יעיל לאחסון ועיבוד מערכים הומוגניים (כלומר, כל האיברים הם מאותו טיפוס נתונים) רב-ממדיים. בניגוד לרשימות פייתון, מערכי ndarray מאוחסנים בזיכרון באופן רציף, מה שמאפשר גישה מהירה וביצועים אופטימליים.

ndarray: מבנה נתונים רב-ממדי, הומוגני ויעיל מבית NumPy, המאפשר אחסון ועיבוד מהיר של נתונים מספריים.

יצירת מערכי ndarray

  • מתוך רשימות פייתון: np.array([1, 2, 3])
  • מערכים מאופסים/אחדות: np.zeros((2, 3)), np.ones((4,))
  • טווחים: np.arange(0, 10, 2), np.linspace(0, 1, 5)
  • נתונים אקראיים: np.random.rand(2, 2)

תכונות חשובות של ndarray

  • .shape: טופל המייצג את מימדי המערך (לדוגמה: (3, 4) למערך 3x4).
  • .ndim: מספר הממדים של המערך.
  • .dtype: טיפוס הנתונים של אלמנטי המערך (לדוגמה: int64, float32).
  • .size: המספר הכולל של אלמנטים במערך.

מערך NumPy (ndarray)

יתרונות: יעילות בזיכרון, מהירות בביצוע פעולות מספריות (בזכות מימוש ב-C), תמיכה מובנית בפעולות וקטוריות, הומוגניות בטיפוס הנתונים.

חסרונות: קשיח יותר בגודלו וטיפוסו לאחר יצירה, פחות גמיש לאחסון טיפוסי נתונים שונים באותו מערך.

רשימת פייתון (Python List)

יתרונות: גמישות רבה (יכולה להכיל טיפוסי נתונים שונים), קלה לשינוי גודל.

חסרונות: פחות יעילה בזיכרון ובביצועים עבור חישובים מספריים גדולים (כל איבר הוא אובייקט פייתון נפרד), דורשת לולאות מפורשות לפעולות על כל האיברים.

פעולות וקטוריות ו-Universal Functions (ufuncs)

אחד היתרונות הגדולים ביותר של NumPy הוא היכולת לבצע פעולות על מערכים שלמים (או תתי-מערכים) מבלי לכתוב לולאות מפורשות בפייתון. פעולות אלו נקראות פעולות וקטוריות והן ממומשות ב-C, מה שמקנה להן מהירות עצומה.

פעולה וקטורית: פעולה המבוצעת על מערך שלם (או תתי-מערך) באופן אלמנט-אחר-אלמנט, ללא צורך בלולאות מפורשות בפייתון, וממומשת ביעילות בשפות ברמה נמוכה.

דוגמאות לפעולות וקטוריות

  • פעולות אריתמטיות: חיבור, חיסור, כפל, חילוק בין מערכים או בין מערך וסקלאר. לדוגמה: arr1 + arr2, arr * 2.
  • פונקציות אוניברסליות (ufuncs): פונקציות הפועלות על כל אלמנט במערך. לדוגמה: np.sqrt(arr), np.sin(arr), np.exp(arr).

Broadcasting

Broadcasting הוא מנגנון חזק ב-NumPy המאפשר לבצע פעולות אריתמטיות על מערכים בעלי צורות (shapes) שונות, בתנאי שצורות אלו תואמות לכללי Broadcasting מסוימים. זהו למעשה הרחבה "וירטואלית" של המערך הקטן יותר כדי להתאים למערך הגדול, מבלי לשכפל נתונים פיזית.

Broadcasting: מנגנון ב-NumPy המאפשר לבצע פעולות על מערכים בעלי צורות שונות, על ידי הרחבה וירטואלית של המערך הקטן יותר כדי להתאים לגדול, תחת כללים ספציפיים.

אינדוקס ופריסה (Indexing and Slicing)

גישה לאלמנטים או תתי-מערכים ב-NumPy דומה לאופן שבו אנו עושים זאת ברשימות פייתון, אך עם הרחבות לטיפול בממדים מרובים.

סוגי אינדוקס

  • אינדוקס בסיסי: גישה לאלמנט יחיד (arr[0], arr[1, 2]) או פריסה (arr[0:5], arr[:, 1]).
  • אינדוקס בוליאני: בחירת אלמנטים על בסיס תנאי לוגי. לדוגמה: arr[arr > 5] יחזיר את כל האלמנטים הגדולים מ-5.
  • אינדוקס "Fancy": שימוש במערכי אינדקסים כדי לבחור אלמנטים לא רציפים. לדוגמה: arr[[0, 2, 4]] יבחר את האלמנטים באינדקסים 0, 2 ו-4.
Views vs. Copies בפריסה: כאשר אנו מבצעים פריסה ב-NumPy (לדוגמה: arr[0:5]), התוצאה היא לרוב view (תצוגה) של המערך המקורי, ולא עותק חדש. משמעות הדבר היא ששינוי ב-view ישפיע גם על המערך המקורי. לעומת זאת, אינדוקס "Fancy" או שימוש בפונקציה .copy() ייצרו עותק נפרד. חשוב להבין הבדל זה כדי למנוע באגים בלתי צפויים בטיפול בנתונים.

ביצועים ויעילות

היתרון המרכזי של NumPy טמון בביצועים. על ידי שימוש במימושים בשפות כמו C ו-Fortran, ועל ידי הימנעות מלולאות פייתון איטיות, NumPy מספקת שיפור דרמטי במהירות החישובים המספריים, במיוחד עבור מערכי נתונים גדולים. אחסון נתונים בזיכרון באופן רציף גם תורם ליעילות הגישה והעיבוד.

  • הימנעות מלולאות פייתון: פעולות וקטוריות מחליפות לולאות Python איטיות בלולאות ממוטבות ב-C.
  • יעילות בזיכרון: אחסון הומוגני ורציף מפחית את צריכת הזיכרון בהשוואה לרשימות פייתון.
  • בסיס למערכת האקולוגית: NumPy הוא הבסיס לספריות רבות אחרות במדעי הנתונים בפייתון, כמו Pandas, SciPy ו-Scikit-learn, המשתמשות במערכי ndarray כפורמט הנתונים המרכזי שלהן.

שאלות לדיון

  • הסבר מדוע NumPy נחשבת ליעילה ומהירה יותר מרשימות פייתון לחישובים מספריים. ציין לפחות שני הבדלים מבניים ותפקודיים.
  • נתון מערך NumPy arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]). כתוב קוד NumPy שיבחר את כל האלמנטים בשורה הראשונה שהם גדולים מ-1, ואת האלמנטים בעמודה השנייה.
  • הסבר את עקרון ה-Broadcasting ב-NumPy ותן דוגמה קצרה הממחישה כיצד הוא מאפשר פעולה בין מערך דו-ממדי לבין מערך חד-ממדי.
  • מה ההבדל המהותי בין "view" ל-"copy" בפריסת מערכי NumPy, ומדוע הבנה זו קריטית למניעת באגים? תן דוגמה קוד קצרה שתמחיש את ההבדל.

נקודות לתשובת מודל

  • NumPy vs. רשימות פייתון: NumPy משתמשת ב-ndarray (הומוגני, רציף בזיכרון, ממומש ב-C) לעומת רשימות פייתון (הטרוגניות, מצביעים לאובייקטים מפוזרים בזיכרון). פעולות וקטוריות ב-NumPy מהירות בהרבה מלולאות פייתון.
  • אינדוקס ופריסה:
    • אלמנטים בשורה הראשונה הגדולים מ-1: arr[0][arr[0] > 1] או arr[0, arr[0] > 1].
    • אלמנטים בעמודה השנייה: arr[:, 1].
  • Broadcasting: מאפשר פעולות בין מערכים עם צורות שונות על ידי הרחבה וירטואלית. לדוגמה: חיבור מטריצה (2D) לוקטור (1D) כאשר הוקטור תואם לאחד הממדים של המטריצה. matrix + vector_row או matrix + vector_column[:, np.newaxis].
  • View vs. Copy:
    • View: פריסה רגילה (לדוגמה: sub_arr = arr[0:2]) יוצרת view. שינוי ב-sub_arr ישנה את arr.
    • Copy: אינדוקס "Fancy" (לדוגמה: sub_arr = arr[[0, 1]]) או שימוש מפורש ב-.copy() (לדוגמה: sub_arr = arr[0:2].copy()) יוצרים עותק נפרד. שינוי ב-sub_arr לא ישפיע על arr.
    • חשיבות: מניעת שינויים לא מכוונים בנתונים המקוריים.
מצאתם טעות או שחסר משהו?
→ הקודמת
תכנות מונחה עצמים (OOP)
הבאה ←
ניתוח נתונים עם Pandas I