6.8. Оператори¶
Перший вид математики, який numpy виконує над ndarray – це стандартні оператори Python. Арифметичні, порівняльні та побітові оператори всі працюють поелементно – кожен оператор проходить масив (або обидва масиви) один раз від початку до кінця в одному виклику бібліотеки, значно швидше, ніж еквівалентний цикл 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, описаними в Типи даних (dtype). Цілочисельні масиви загортаються при переповненні; приведіть до ширшого dtype перед операцією, коли це важливо.
Оператор матричного множення @ не реалізований. Використовуйте dot() для матричних/векторних добутків.
6.8.1.1. Форми на місці¶
Кожен арифметичний оператор має форму на місці – +=, -=, *=, /=, %=, **=. Форма на місці записує результат у наявний буфер замість виділення тимчасового:
b = b + 1 # allocates a temporary the size of b
b += 1 # no temporary
На мікроконтролері друга форма є фактично обов’язковою для будь-якого гарячого циклу.
6.8.2. Побітові операції¶
Побітові оператори &, |, ^ працюють поелементно на цілочисельних масивах. Застосовані до масиву float або complex вони підіймають 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)
Унарний оператор ~ виконує побітове NOT на цілочисельному масиві.
Оператори зсуву << та >> не підключені на рівні оператора Python. Функціональні форми left_shift() та right_shift() працюють:
np.left_shift(a, 2)
np.right_shift(b, 1)
6.8.3. Порівняння¶
==, !=, <, <=, >, >= всі повертають bool ndarray форми транслювання:
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 підіймає 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. Унарні оператори¶
+a– повертає копію масиву.-a– заперечення. На беззнакових dtype значення загортаються за модулем \(2^N\), так само, як і бінарні оператори.abs(a)– поелементне абсолютне значення. На беззнакових dtype повертає копію без обчислень.~a– побітова інверсія (лише для цілочисельних масивів).len(a)– повертає довжину першої осі, відповідно до конвенції Python-послідовності.
6.8.5. Чого не вистачає¶
Оператори правої частини для порівняльних та деяких побітових операцій не реалізовані так само, як арифметичні оператори. Використовуйте функціональні форми (наведені вище), коли ndarray опиняється праворуч.
Для повного списку підтримуваних операторів та правил розширення, які вони дотримуються, дивіться numpy — операції з масивами, сумісні з numpy.