So let's say I have a numpy array a= np.array([1,2,3,4,5]) and a value x=4, then I want to create a numpy array of values -1 and 1 where there is a 1 in the 4th position and -1 everywhere else.
Here is what I tried:
for i in range(a):
if i == x:
a[i]=1
else:
a[i]=-1
Is this good?
No, this is not numpy'ish
b=-np.ones(a.shape)
b[x] = 1
Edit: added example
import numpy as np
x=3
a= np.array([1, 2, 3, 4, 5])
b=-np.ones(a.shape)
b[x] = 1
print(b)
> [-1. -1. -1. 1. -1.]
Try:
import numpy as np
a= np.array([1,2,3,4,5])
x=np.where(a==4, 1, -1)
print(x)
Output:
[-1 -1 -1 1 -1]
[Program finished]
try this:
b = np.array([1 if i == 4 else -1 for i in range(a.shape)])
Another alternative. Utilizes casting from bool to int.
b=2*(a==x)-1
Related
I have vectors with 0 and 1.
a = np.array([1,1,0,0])
b = np.array([1,0,0,1])
c = np.array([0 1 1 0])
d = np.array([0 1 0 1])
I would like to implement a function checking if the 1 are consecutive in the vector by disregarding the end of the vector, i.e. last element wih first element. Expected results will be:
check(a) --> True
check(b) --> True
check(c) --> True
check(d) --> False
The easy solution will be to scroll through each vector. However I feel that an easier and smarter is doable with some np.diff or np.nonzero combination. Any idea?
Thanks a lot.
You could use np.roll + np.logical_and + np.count_nonzero
import numpy as np
def check(arr):
return np.count_nonzero(np.logical_and(np.roll(arr, 1), arr)) > 0
a = np.array([1, 1, 0, 0])
b = np.array([1, 0, 0, 1])
c = np.array([0, 1, 1, 0])
d = np.array([0, 1, 0, 1])
print(check(a))
print(check(b))
print(check(c))
print(check(d))
Output
True
True
True
False
Maybe you can try something like this,
def check(k):
return any( i in np.diff(np.where(k==1)) for i in [1, len(k)-1])
np.where(k==1), this will return a list of indices where your vector is 1.
np.diff(np.where(k==1)), this will evalute the difference between consequative indices where your vector is 1.
Finally any( i in np.diff(np.where(k==1)) for i in [1, len(k)-1]) this will check if there are consecutive 1's. Either if their difference is 1 or length of your vector - 1.
In matalb we can have a vector as a=[1,3,4] and use it to access and replace elements of another vector or matrix, like this.
a=[1,2,4];
b=[1,2,3,4];
b(a)=1
so b would be [1,1,3,1]
Is there anyway to do this in python?
I know I can do stuff like this:
a=[1,2,4]
b=list(range(1,10))
[b[x] for x in a]
but it doesn't alow me to replace the values, for example.
Numpy has similar functionality. However, keep in mind that Numpy indexing starts at 0. not at 1:
import numpy as np
a = np.array([1, 2, 4])
b = np.array([1, 2, 3, 4])
b[a - 1] = 1
print(b)
#[1 1 3 1]
you can also use logical indexing in python:
import numpy as np
a = np.array([1,1,1,0])
b = np.array([5,6,7,8])
b[a==True]=1
#[1 1 1 8]
I am trying to normalize each row vector of numpy array x, but I'm facing 2 problems.
I'm unable to update the row vectors of x (source code in image)
Is it possible to avoid the for loop (line 6) with any numpy functions?
import numpy as np
x = np.array([[0, 3, 4] , [1, 6, 4]])
c = x ** 2
for i in range(0, len(x)):
print(x[i]/np.sqrt(c[i].sum())) #prints [0. 0.6 0.8]
x[i] = x[i]/np.sqrt(c[i].sum())
print(x[i]) #prints [0 0 0]
print(x) #prints [[0 0 0] [0 0 0]] and wasn't updated
I've just recently started out with numpy, so any assistance would be greatly appreciated!
I'm unable to update the row vectors of x (source code in image)
Your np.array has no dtype argument, so it uses <type 'numpy.int32'>. If you wish to store floats in the array, add a float dtype:
x = np.array([
[0,3,4],
[1,6,4]
], dtype = np.float)
To see this, compare
x = np.array([
[0,3,4],
[1,6,4]
], dtype = np.float)
print type(x[0][0]) # output = <type 'numpy.float64'>
to
x = np.array([
[0,3,4],
[1,6,4]
])
print type(x[0][0]) # output = <type 'numpy.int32'>
is it possible to avoid the for loop (line 6) with any numpy functions?
This is how I would do it:
norm1, norm2 = np.linalg.norm(x[0]), np.linalg.norm(x[1])
print x[0] / norm1
print x[1] / norm2
You can use:
x/np.sqrt((x*x).sum(axis=1))[:, None]
Example:
In [9]: x = np.array([[0, 3, 4] , [1, 6, 4]])
In [10]: x/np.sqrt((x*x).sum(axis=1))[:, None]
Out[10]:
array([[0. , 0.6 , 0.8 ],
[0.13736056, 0.82416338, 0.54944226]])
For the first question:
x = np.array([[0,3,4],[1,6,4]],dtype=np.float32)
For the second question:
x/np.sqrt(np.sum(x**2,axis=1).reshape((len(x),1)))
Given 2-dimensional array
x = np.array([[0, 3, 4] , [1, 6, 4]])
Row-wise L2 norm of that array can be calculated with:
norm = np.linalg.norm(x, axis = 1)
print(norm)
[5. 7.28010989]
You can not divide array x of shape (2, 3) by norm of shape (2,), the following trick enables that by adding extra dimension to norm
# Divide by adding extra dimension
x = x / norm[:, None]
print(x)
[[0. 0.6 0.8 ]
[0.13736056 0.82416338 0.54944226]]
This solves both your questions
[A,I] = histc([0.9828 0.4662 0.5245 0.9334 0.2163],[0.0191 0.2057 0.2820 0.2851 1.0000])
That is the MATLAB code with the results:
A =
0 1 0 4 0
I =
4 4 4 4 2
What I need is I. I've tried using np.histogram but it gives me this:
>>> a,b = np.histogram([0.9828 , 0.4662 , 0.5245 , 0.9334 , 0.2163],[0.0191 , 0.2057 , 0.2820 , 0.2851 , 1.0000])
>>> a
array([0, 1, 0, 4])
>>> b
array([ 0.0191, 0.2057, 0.282 , 0.2851, 1. ])
I want to get the bins that each element in my array/matrix goes into.
What you are looking for is numpy.digitize:
Return the indices of the bins to which each value in input array belongs.
>>> a = np.digitize([0.9828 , 0.4662 , 0.5245 , 0.9334 , 0.2163],[0.0191 , 0.2057 , 0.2820 , 0.2851 , 1.0000])
>>> print(a)
[4 4 4 4 2]
A correct python implementation of matlab's histc is the following:
import numpy as np
def histc(x, binranges):
indices = np.searchsorted(binranges, x)
return np.mod(indices+1, len(binranges)+1)
Correct implementation of MATLAB histc function in python (source).
def histc(x, bins):
map_to_bins = np.digitize(x, bins) # Get indices of the bins to which each value in input array belongs.
res = np.zeros(bins.shape)
for el in map_to_bins:
res[el-1] += 1 # Increment appropriate bin.
return res
numpy.digitize alone is not a complete reproduction of Matlab histc. This works:
import numpy as np
def histc(X, bins):
map_to_bins = np.digitize(X,bins)
r = np.zeros(bins.shape)
for i in map_to_bins:
r[i-1] += 1
return [r, map_to_bins]
if __name__=="__main__":
X = np.array([0.9828, 0.4662, 0.5245, 0.9334, 0.2163])
bins = np.array([0.0191, 0.2057, 0.2820, 0.2851, 1.0])
[A,I] = histc(X, bins)
print("X", X)
print("bins", bins)
print("A",A,"expecting", [0, 1, 0, 4, 0])
print("I",I,"expecting", [4, 4, 4, 4, 2])
I am very new to programming. I have code in matlab:
x2(x2>=0)=1;
x2(x2<0)=-1;
%Find values in x2 which are less than 0 and replace them with -1,
%where x2 is an array like
0,000266987932788242
0,000106735120804439
-0,000133516844874253
-0,000534018243439120
I tried to do this in Python using code
if x2>=0:
x2=1
if x2<0:
x2=-1
This returns ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
How should I do it so that I get all the positive replaced by 1 and negatives by -1 and STORE all of this in the x2 for example, not just print, so that I could use it later to do some other stuff.
You can use numpy's ability to index over boolean array.
import numpy as np
x = np.array([-5.3, -0.4, 0.6, 5.4, 0.0])
not_neg = x >= 0 # creates a boolean array
x[not_neg] = 1 # index over boolean array
x[~not_neg] = -1
Result:
>>> x
array([-1., -1., 1., 1., 1.])
First:
x2 = [0.000266987932788242, 0.000106735120804439, -0.000133516844874253, -0.000534018243439120]
print [1 if num >= 0 else num for num in x2]
Output
[1, 1, -0.000133516844874253, -0.000534018243439120]
Second:
x2 = [-1, 2, -3, 4]
print [-1 if num < 0 else num for num in x2]
Output
[0.000266987932788242, 0.000106735120804439, -1, -1]
If you need both of them in a single statement
x2 = [0.000266987932788242, 0.000106735120804439, -0.000133516844874253, -0.000534018243439120]
x2 = [-1 if num < 0 else 1 for num in x2]
print x2
Output
[1, 1, -1, -1]