DR. IGOR DATA SCIENCEAI, Data & Creativity · From Data to Impact
Python Lab
מעבדת Python · שיעור 1

וקטורים ב-NumPy הדברים החשובים והמלכודות

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

Math vector
NumPy array
01

כלל העבודה

לא להריץ מיד.

Predict

כתבו מה לדעתכם יודפס.

Run

חשפו את הפלט והשוו.

Explain

הסבירו את ההבדל בין Python למתמטיקה.

02

10 תחנות עבודה

מן הבסיס ועד מלכודות חשובות.

Lab 01

List לעומת NumPy

לפני הרצה: מה יודפס?
Pythonpredict → reveal → explain
x = [1, 2, 3]
print(2 * x)
[1, 2, 3, 1, 2, 3]
למה?
ברשימה, הכפל חוזר על הרשימה. במערך NumPy הוא כפל בסקלר.
הגרסה הנכונה / ההרחבה
x = np.array([1, 2, 3])
print(2 * x)  # [2 4 6]
Lab 02

אינדקסים ו-slicing

לפני הרצה: מה יודפס?
Pythonpredict → reveal → explain
x = np.array([10, 20, 30, 40, 50])
print(x[-1])
print(x[1:4])
50 [20 30 40]
למה?
האינדקס השלילי בוחר מן הסוף; הגבול הימני של slice אינו נכלל.
הגרסה הנכונה / ההרחבה
# Mathematical x_{2:4} corresponds to Python x[1:4]
Lab 03

Aliasing לעומת copy

לפני הרצה: מה יהיה x?
Pythonpredict → reveal → explain
x = np.array([1, 2, 3])
y = x
y[0] = 99
print(x)
[99 2 3]
למה?
x ו-y מצביעים לאותו מערך.
הגרסה הנכונה / ההרחבה
y = x.copy()  # independent array
Lab 04

Scalar, list, array

לפני הרצה: האם אלה אותו סוג?
Pythonpredict → reveal → explain
a = 5
b = [5]
c = np.array([5])

print(type(a))
print(len(b))
print(c.shape)
1 (1,)
למה?
סקלר, רשימה באורך 1 ומערך באורך 1 אינם אותו אובייקט.
הגרסה הנכונה / ההרחבה
# 1-vector in mathematics is often identified with a scalar,
# but code keeps them distinct.
Lab 05

Stacking נכון

לפני הרצה: איזו פקודה יוצרת וקטור שטוח?
Pythonpredict → reveal → explain
x = np.array([1, 2])
y = np.array([10, 20, 30])

print(np.concatenate([x, y]))
[ 1 2 10 20 30]
למה?
רשימה [x,y] היא רשימה של שני מערכים, לא וקטור שטוח.
הגרסה הנכונה / ההרחבה
z = np.concatenate([x, y])
Lab 06

Broadcasting

לפני הרצה: מה ההבדל בין שתי השורות?
Pythonpredict → reveal → explain
x = np.array([1, 2, 3])

print(5 * x)
print(5 + x)
[ 5 10 15] [6 7 8]
למה?
הראשונה היא כפל בסקלר; השנייה מוסיפה אותו סקלר לכל איבר.
הגרסה הנכונה / ההרחבה
# NumPy broadcasts the scalar across the vector.
Lab 07

Elementwise מול dot product

לפני הרצה: מה סוג התוצאה בכל שורה?
Pythonpredict → reveal → explain
x = np.array([2, 3, 4])
y = np.array([5, 0, -1])

print(x * y)
print(x @ y)
[10 0 -4] 6
למה?
* מחזיר וקטור של מכפלות; @ מחבר אותן ומחזיר סקלר.
הגרסה הנכונה / ההרחבה
np.dot(x, y)  # same scalar result
Lab 08

מסכות ו-NNZ

לפני הרצה: כמה איברים חיוביים וכמה לא-אפסיים?
Pythonpredict → reveal → explain
x = np.array([0, -2, 0, 5, 7, 0])

print((x > 0).sum())
print(np.count_nonzero(x))
2 3
למה?
מסכה בוליאנית מאפשרת לספור תנאי; NNZ סופר כל איבר שאינו אפס.
הגרסה הנכונה / ההרחבה
positive = x[x > 0]
Lab 09

וקטור הפרשים

לפני הרצה: מה מחזיר הקוד?
Pythonpredict → reveal → explain
x = np.array([10, 13, 12, 20, 25])
d = x[1:] - x[:-1]
print(d)
[ 3 -1 8 5]
למה?
שני slices מוזזים באותו אורך נותנים הפרשים עוקבים.
הגרסה הנכונה / ההרחבה
# Equivalent to mathematical x_{2:n} - x_{1:n-1}
Lab 10

השוואת מערכים

לפני הרצה: מה מחזירה כל בדיקה?
Pythonpredict → reveal → explain
x = np.array([1, 2, 3])
y = np.array([1, 2, 3])

print(x == y)
print(np.array_equal(x, y))
[ True True True] True
למה?
== ב-NumPy פועל איבר-איבר; array_equal מחזיר ערך בוליאני אחד.
הגרסה הנכונה / ההרחבה
# For approximate floating-point equality:
np.allclose(x, y)
03

מפת המלכודות

לשמור ליד המחשב.

List × scalar

ברשימה מתקבלת חזרה, לא כפל מתמטי.

Index 0

האיבר המתמטי הראשון נמצא באינדקס 0.

Right endpoint

ב-x[a:b] האינדקס b אינו נכלל.

Aliasing

y=x אינו יוצר עותק.

* מול @

הראשון איבר-איבר; השני מכפלה פנימית.

== ב-NumPy

מחזיר מערך בוליאני, לא ערך אחד.

Scalar מול 1-vector

במתמטיקה לעיתים מזהים; בקוד לא.

Shapes

לפני פעולה בדקו שהממדים מתאימים.

04

Take-home message

המעבר מווקטור מתמטי לקוד דורש בדיקת טיפוס, shape ואופרטור.

לפני כל פעולה

בדקו type, shape והאם נדרש וקטור או סקלר.

אחרי כל פעולה

בדקו פלט קטן ביד לפני עבודה עם נתונים גדולים.