6.8. ตัวดำเนินการ

คณิตศาสตร์ประเภทแรกที่ numpy ทำงานบน ndarray คือตัวดำเนินการ Python มาตรฐาน ตัวดำเนินการเลขคณิต การเปรียบเทียบ และแบบบิตไวส์ล้วนทำงาน แบบ element-wise -- แต่ละตัวดำเนินการเดินผ่านอาร์เรย์ (หรือทั้งสองอาร์เรย์) ครั้งเดียวจากต้นจนจบภายในการเรียกไลบรารีครั้งเดียว เร็วกว่าลูป Python for ที่เทียบเท่ามาก

6.8.1. เลขคณิต

+, -, *, /, //, %, ** ล้วนทำงานระหว่างอาร์เรย์สองตัวที่มีรูปร่างเข้ากันได้ หรือระหว่างอาร์เรย์กับสเกลาร์:

a = np.array([1, 2, 3, 4], dtype=np.float)
b = np.array([10, 20, 30, 40], dtype=np.float)

print(a + b)        # array([11.0, 22.0, 33.0, 44.0])
print(a * 2)        # array([2.0, 4.0, 6.0, 8.0])
print(b - a)        # array([9.0, 18.0, 27.0, 36.0])
print(b / a)        # array([10.0, 10.0, 10.0, 10.0])

dtype ของผลลัพธ์ตามกฎการ upcast ที่อธิบายไว้ใน Dtypes อาร์เรย์จำนวนเต็มจะ wrap เมื่อ overflow แคสต์ไปยัง dtype ที่กว้างกว่าก่อนการดำเนินการเมื่อสิ่งนั้นมีความสำคัญ

ตัวดำเนินการคูณเมทริกซ์ @ ไม่ ถูกนำมาใช้ ใช้ dot() สำหรับผลคูณเมทริกซ์/เวกเตอร์

6.8.1.1. รูปแบบ in-place

ตัวดำเนินการเลขคณิตทุกตัวมีรูปแบบ in-place -- +=, -=, *=, /=, %=, **= รูปแบบ in-place เขียนผ่านบัฟเฟอร์ที่มีอยู่แทนที่จะจัดสรรค่าชั่วคราว:

b = b + 1            # allocates a temporary the size of b
b += 1               # no temporary

บนไมโครคอนโทรลเลอร์ รูปแบบที่สองนี้จำเป็นอย่างยิ่งสำหรับทุกลูปที่ทำงานบ่อย

6.8.2. Bitwise

ตัวดำเนินการแบบบิตไวส์ &, |, ^ ทำงานแบบ element-wise บนอาร์เรย์จำนวนเต็ม เมื่อใช้กับอาร์เรย์ float หรือ complex จะ raise TypeError

a = np.array([0b1100, 0b1010], dtype=np.uint8)
b = np.array([0b1010, 0b1100], dtype=np.uint8)
print(a & b)        # array([8, 8], dtype=uint8)
print(a | b)        # array([14, 14], dtype=uint8)
print(a ^ b)        # array([6, 6], dtype=uint8)

~ แบบ unary ทำการ NOT แบบบิตไวส์บนอาร์เรย์จำนวนเต็ม

ตัวดำเนินการ shift << และ >> ไม่ ถูกเชื่อมต่อที่ระดับตัวดำเนินการ Python รูปแบบฟังก์ชัน left_shift() และ right_shift() ทำงานได้:

np.left_shift(a, 2)
np.right_shift(b, 1)

6.8.3. การเปรียบเทียบ

==, !=, <, <=, >, >= ล้วนคืนค่า bool ndarray ตามรูปร่าง broadcast:

a = np.array([1, 2, 3, 4, 5], dtype=np.uint8)
print(a < 3)
# array([True, True, False, False, False], dtype=bool)

ผลลัพธ์บูลีนคือสิ่งที่ การจัดทำดัชนี และ การเลือก ใช้งาน

6.8.3.1. กฎด้าน

ndarray ต้อง อยู่ ทางซ้าย ของตัวดำเนินการเชิงสัมพันธ์เมื่อเปรียบเทียบกับสเกลาร์ a > 2 ทำงานได้ 2 < a จะ raise TypeError สำหรับรูปแบบที่สมมาตร ใช้ชื่อฟังก์ชัน:

np.greater(5, a)        # 5 > a, element-wise
np.less(5, a)           # 5 < a, element-wise
np.equal(5, a)          # 5 == a, element-wise
np.not_equal(5, a)      # 5 != a, element-wise

6.8.4. ตัวดำเนินการ unary

  • +a -- คืนค่าสำเนาของอาร์เรย์

  • -a -- การนิเสธ บน dtype ที่ไม่มีเครื่องหมาย ค่าจะ wrap ตัวประกอบ \(2^N\) เหมือนกับที่ตัวดำเนินการไบนารีทำ

  • abs(a) -- ค่าสัมบูรณ์แบบ element-wise บน dtype ที่ไม่มีเครื่องหมาย คืนสำเนาโดยไม่คำนวณ

  • ~a -- การกลับบิตไวส์ (เฉพาะอาร์เรย์จำนวนเต็มเท่านั้น)

  • len(a) -- คืนความยาวของแกน แรก ตรงกับข้อตกลง sequence ของ Python

6.8.5. สิ่งที่ขาดหายไป

ตัวดำเนินการด้านขวาสำหรับการเปรียบเทียบและบางส่วนของการดำเนินการแบบบิตไวส์ไม่ได้ถูกนำมาใช้ในลักษณะเดียวกับตัวดำเนินการเลขคณิต ใช้รูปแบบฟังก์ชัน (ด้านบน) เมื่อ ndarray จะอยู่ทางขวา

สำหรับรายการตัวดำเนินการที่รองรับทั้งหมดและการ upcast ที่ตามมา ดูที่ numpy --- การดำเนินการอาร์เรย์ที่เข้ากันได้กับ numpy