I have to apply a function which devide a value by another to every row of an numpy array.
here the function:
def myfunc(a, b):
return (a/b)
my numpy ndarray look like this and it represent the "a" value:
[[ 1 2 3 4 ]
[ 5 6 7 8 ]]
and my list which is my b value, looks like this:
[1, 2, 3, 4]
The result I want is :
[[1 1 1 1]
[5 3 2.33 2]]
To do that, I can't use a loop, so I tried with np.vectorize. Here my code:
test = np.vectorize(myfunc)
test(a, b)
this return :
array([[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
[1]
<NDArray 1 #cpu(0)>,
[1]
<NDArray 1 #cpu(0)>,
[1]
<NDArray 1 #cpu(0)>,
[1]
<NDArray 1 #cpu(0)>]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],
...
so every cell is devide4 times by the first value of b.
but for an unknown reason my code do not work for the ndarray. when I tried with an normal array, it's working. Example:
a = np.array([[1, 2, 3, 4], [5,6,7,8]])
b = [1,2,3,4]
def my(coord, shape):
return (coord/shape)
myfunc = np.vectorize(my)
myfunc(a, b)
result:
array([[1. , 1. , 1. , 1. ],
[5. , 3. , 2.33333333, 2. ]])
Do you guys know what I can do ? I really don't know how I get the ndarray, and why I can't have the right result.
Why do you need np.vectorize?
In [511]: a = np.array([[1, 2, 3, 4], [5,6,7,8]])
...: b = [1,2,3,4]
In [512]: b = np.array(b)
In [513]: a.shape
Out[513]: (2, 4)
In [514]: b.shape
Out[514]: (4,)
In [515]: a / b
Out[515]:
array([[1. , 1. , 1. , 1. ],
[5. , 3. , 2.33333333, 2. ]])
Related
I have the following function that calculates the eucledian distance between all combinations of the vectors in Matrix A and Matrix B
def distance_matrix(A,B):
n=A.shape[1]
m=B.shape[1]
C=np.zeros((n,m))
for ai, a in enumerate(A.T):
for bi, b in enumerate(B.T):
C[ai][bi]=np.linalg.norm(a-b)
return C
This works fine and creates an n*m-Matrix from a d*n-Matrix and a d*m-Matrix containing the eucledian distance between all combinations of the column vectors.
>>> print(A)
[[-1 -1 1 1 2]
[ 1 -1 2 -1 1]]
>>> print(B)
[[-2 -1 1 2]
[-1 2 1 -1]]
>>> print(distance_matrix(A,B))
[[2.23606798 1. 2. 3.60555128]
[1. 3. 2.82842712 3. ]
[4.24264069 2. 1. 3.16227766]
[3. 3.60555128 2. 1. ]
[4.47213595 3.16227766 1. 2. ]]
I spent some time looking for a numpy or scipy function to achieve this in a more efficient way. Is there such a function or what would be the vecotrized way to do this?
You can use:
np.linalg.norm(A[:,:,None]-B[:,None,:],axis=0)
or (totaly equivalent but without in-built function)
((A[:,:,None]-B[:,None,:])**2).sum(axis=0)**0.5
We need a 5x4 final array so we extend our array this way:
A[:,:,None] -> 2,5,1
↑ ↓
B[:,None,:] -> 2,1,4
A[:,:,None] - B[:,None,:] -> 2,5,4
and we apply our sum over the axis 0 to finally get a 5,4 ndarray.
Yes, you can broadcast your vectors:
A = np.array([[-1, -1, 1, 1, 2], [ 1, -1, 2, -1, 1]])
B = np.array([[-2, -1, 1, 2], [-1, 2, 1, -1]])
C = np.linalg.norm(A.T[:, None, :] - B.T[None, :, :], axis=-1)
print(C)
array([[2.23606798, 1. , 2. , 3.60555128],
[1. , 3. , 2.82842712, 3. ],
[4.24264069, 2. , 1. , 3.16227766],
[3. , 3.60555128, 2. , 1. ],
[4.47213595, 3.16227766, 1. , 2. ]])
You can get an explanation of how it works here:
https://sparrow.dev/pairwise-distance-in-numpy/
I have a feature matrix that I want to row normalize.
This is what I have done based on min-max scaling and I am getting an error. Can anyone help me with this error.
a = np.random.randint(10, size=(4,5))
s=a.max(axis=1) - a.min(axis=1)
np.amax(a,axis=1)
print(s)
(a - a.min(axis=1))/(a.max(axis=1) - a.min(axis=1))\
>>[7 6 4 5]
4 print(s)
5
----> 6 (a - a.min(axis=1))/(a.max(axis=1) - a.min(axis=1))
ValueError: operands could not be broadcast together with shapes (4,5) (4,)
Try to work with transposed matrix:
b = a.T
m = (b - b.min(axis=0)) / (b.max(axis=0) - b.min(axis=0))
m = m.T
>>> a
array([[2, 3, 2, 8, 3], # min=2 -> 0, max=8 -> 1
[3, 3, 9, 2, 1], # min=1 -> 0, max=9 -> 1
[1, 9, 8, 4, 7], # min=1 -> 0, max=9 -> 1
[6, 8, 7, 9, 4]]) # min=4 -> 0, max=9 -> 1
>>> m
array([[0. , 0.16666667, 0. , 1. , 0.16666667],
[0.25 , 0.25 , 1. , 0.125 , 0. ],
[0. , 1. , 0.875 , 0.375 , 0.75 ],
[0.4 , 0.8 , 0.6 , 1. , 0. ]])
I have an alternative solution , I am not sure if this one is correct.Would be great if someone can comment on it.
def row_normalize(mf):
row_sums = np.array(mf.sum(1))
new_matrix = mf / row_sums[:, np.newaxis]
return new_matrix
I am trying to add random values to a specific amount of values in a numpy array to mutate weights of my neural network. For example, 2 of the values in this array
[ [0 1 2]
[3 4 5]
[6 7 8] ]
are supposed to be mutated (i. e. a random value between -1 and 1 is added to them). The result may look something like this then:
[ [0 0.7 2]
[3 4 5]
[6.9 7 8]]
I would prefer a solution without looping, as my real problem is a little bigger than a 3x3 matrix and looping usually is inefficient.
Here's one way based on np.random.choice -
def add_random_n_places(a, n):
# Generate a float version
out = a.astype(float)
# Generate unique flattened indices along the size of a
idx = np.random.choice(a.size, n, replace=False)
# Assign into those places ramdom numbers in [-1,1)
out.flat[idx] += np.random.uniform(low=-1, high=1, size=n)
return out
Sample runs -
In [89]: a # input array
Out[89]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [90]: add_random_n_places(a, 2)
Out[90]:
array([[0. , 1. , 2. ],
[2.51523009, 4. , 5. ],
[6. , 7. , 8.36619255]])
In [91]: add_random_n_places(a, 4)
Out[91]:
array([[0.67792859, 0.84012682, 2. ],
[3. , 3.71209157, 5. ],
[6. , 6.46088001, 8. ]])
You can use np.random.rand(3,3) to create a 3x3 matrix with [0,1) random values.
To get (-1,1) values try np.random.rand(3,3) - np.random.rand(3,3) and add this to a matrix you want to mutate.
I have three set of matrix and I am required to produce the desired output. The problem is I didn't know the operation to solve the matrix.
The matrix:
a= [[1]
[1]
[0]
[0]]
b= [[ 1. ]
[-0.5 ]
[-0.8660254]
[ 0. ]]
c= [[ 1]
[-1]
[ 0]
[ 0]]
Using the three matrix, I need to produce the result of
d=[[ 1]
[0.5]
[0.86]
[0]]
So what is a?b?c?=d. I hope anyone may help me. Thank you.
Use this code to get the desired result. First, convert the lists to arrays and then perform the following operation.
a= np.array([[1],[1],[0],[0]])
b= np.array([[ 1. ],[-0.5 ],[-0.8660254],[ 0. ]])
c= np.array([[ 1],[-1],[ 0],[ 0]])
d=np.array([[ 1],[0.5],[0.86], [0]])
a-b+c
array([[1. ],
[0.5 ],
[0.8660254],
[0. ]])
The answer is simply:
a - b + c = d
I've been trying to create a watershed algorithm and as all the examples seem to be in Python I've run into a bit of a wall. I've been trying to find in numpy documentation what this line means:
matrixVariable[A==255] = 0
but have had no luck. Could anyone explain what that operation does?
For context the line in action: label [lbl == -1] = 0
The expression A == 255 creates a boolean array which is True where x == 255 in A and False otherwise.
The expression matrixVariable[A==255] = 0 sets each index corresponding to a True value in A == 255 to 0.
EG:
import numpy as np
A = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
B = np.zeros([3, 3])
print('before:')
print(B)
B[A>5] = 5
print('after:')
print(B)
OUT:
[[ 0. 0. 0.]
[ 0. 0. 0.]
[ 0. 0. 0.]]
after:
[[ 0. 0. 0.]
[ 0. 0. 5.]
[ 5. 5. 5.]]
I assumed that matrixVariable and A are numpy arrays. If the assumption is correct then "matrixVariable[A==255] = 0" expression first gets the index of the array A where values of A are equal to 255 then gets the values of matrixVariable for those index and set them to "0"
Example:
import numpy as np
matrixVariable = np.array([(1, 3),
(2, 2),
(3,1)])
A = np.array([255, 1,255])
So A[0] and A[2] are equal to 255
matrixVariable[A==255]=0 #then sets matrixVariable[0] and matrixVariable[2] to zero
print(matrixVariable) # this would print
[[0 0]
[2 2]
[0 0]]