Ufunc
ufunc operates only on ndarrays. The purpose of ufunc is to vectorize loops.
Let's say we want to add two ndarrays of the same dimensions. We can use python's built-in .zip() function and a for loop:
import numpy as np
# ndarrays must be the same size
no1 = [7 8 9 10 1 12 13 14]
no2 = [17 28 9 120 11 122 1300 314]
no3 = []
# i iterates over no1 and j iterates over no2
for i,j in zip(no1, no2)
z.append(i+j)
print(no3)
# result is
[24, 36, 18, 130, 12, 134, 1313, 328]
Or we can use ndarrays and its .add() method.
import numpy as np
# ndarrays must be the same size
no1 = np.ndarray([7, 8, 9, 10, 1, 12, 13, 14])
no2 = np.ndarray([17, 28, 9, 120, 11, 122, 1300, 314])
no3 = np.add(no1, no2)
print(no3)
# result is same as before
[ 24 36 18 130 12 134 1313 328]
What happens if the two arrays are not the same size:
import numpy as np
# ndarrays must be the same size
no1 = np.ndarray([7, 8, 9, 10, 1, 12, 13]) # 7 elements
no2 = np.ndarray([17, 28, 9, 120, 11, 122, 1300, 314]) # 8 elements
no3 = np.add(no1, no2)
print(no3)
ValueError: operands could not be broadcast together with shapes (8,) (7,)
What happens if the two arrays are the same size, but with different dimensions:
import numpy as np
# ndarrays must be the same size
no1 = np.ndarray([7], [8], [9], [10], [1], [12], [13], [14]]) # 8 elements in one column
no2 = np.ndarray([17, 28, 9, 120, 11, 122, 1300, 314]) # 8 elements in one row
no3 = np.add(no1, no2)
print(no1)
# results in:
[[ 24 35 16 127 18 129 1307 321]
[ 25 36 17 128 19 130 1308 322]
[ 26 37 18 129 20 131 1309 323]
[ 27 38 19 130 21 132 1310 324]
[ 18 29 10 121 12 123 1301 315]
[ 29 40 21 132 23 134 1312 326]
[ 30 41 22 133 24 135 1313 327]
[ 31 42 23 134 25 136 1314 328]]
Which is 8 by 8 square and all of the normally summed elements make a trace along the diagonal. The off-diagonal elements go something like this: take no2, transpose it into a column vector, then shift it from left to right, hold while the element of no1 is added to each of no2, then shift the original no2 again one column to the right, and repeat.
There is also a .multiply() method
import numpy as np
x = [1, 2, 3, 4]
y = [4, 5, 6, 7]
z = np.multiply(x,y)
print(z)
[ 4 10 18 28]
Finally, .zip() can produced some unusual results when used in non-standard ways
import numpy as np
x = [1, 2, 3, 4]
y = [4, 5, 6, 7]
z = []
for j in zip(y, x):
z.append(j + j)
print(z)
[(4, 1, 4, 1), (5, 2, 5, 2), (6, 3, 6, 3), (7, 4, 7, 4)]
z = []
for i in zip(y, x):
z.append(i + i)
print(z)
[(4, 1, 4, 1), (5, 2, 5, 2), (6, 3, 6, 3), (7, 4, 7, 4)]
z = []
for i in zip(y, x):
z.append(i)
print(z)
[(4, 1), (5, 2), (6, 3), (7, 4)]
In these non-standard cases, there is no addition done by zip, but rather appending and repeating of elements.
No comments:
Post a Comment