How to make operations between part of array with part of array? - python

import numpy as np
a=np.array([2,3,4,6,7,4,5,3,2,1,9,8,7,6,4,2])
## a has 16 elements
b=np.array([1,5,3,7])
""" i want this:
a[:4] - b[1], a[4:8]-b[2], a[8:12]-b[3], a[12:16]-b[4] in one array
and it should look like
c=numpy.array[1,2,3,5,2,-1,0,-2....]
This is just a simple example for my problem. So can not be done with using groups. I need a loop to solve this.

You can reshape your array a, make operations on that and than flatten back.
In [24]: import numpy as np
In [25]: a=np.array([2,3,4,6,7,4,5,3,2,1,9,8,7,6,4,2])
In [26]: b=np.array([1,5,3,7])
In [27]: (a.reshape(4,4).T - b).T.ravel()
Out[27]: array([ 1, 2, 3, 5, 2, -1, 0, -2, -1, -2, 6, 5, 0, -1, -3, -5])

Related

Replace occurences of a numpy array in another numpy array with a value

I have a 2D numpy array:
[[1,2,3,4,5],[2,4,5,6,7],[0,9,3,2,4]]
I also have a second 1D array:
[2,3,4]
I want to replace all occurences of the elements of the second array with 0
So eventually, my second array should look like
[[1,0,0,0,5],[0,0,5,6,7],[0,9,0,0,0]]
is there a way in python/numpy I can do this without using a loop.
I already checked at np.where, but the condition there is only for example where element = 1 value, and not multiple.
Thanks a lot !
Use numpy.isin.
>>> import numpy as np
>>> a = np.array([[1,2,3,4,5],[2,4,5,6,7],[0,9,3,2,4]])
>>> b = np.array([2,3,4])
>>> a[np.isin(a, b)] = 0
>>> a
array([[1, 0, 0, 0, 5],
[0, 0, 5, 6, 7],
[0, 9, 0, 0, 0]])

get maximum of absolute along axis

I have a couple of ndarrays with same shape, and I would like to get one array (of same shape) with the maximum of the absolute values for each element. So I decided to stack all arrays, and then pick the values along the new stacked axis. But how to do this?
Example
Say we have two 1-D arrays with 4 elements each, so my stacked array looks like
>>> stack
array([[ 4, 1, 2, 3],
[ 0, -5, 6, 7]])
If I would just be interested in the maximum I could just do
>>> numpy.amax(stack, axis=0)
array([4, 1, 6, 7])
But I need to consider negative values as well, so I was going for
>>> ind = numpy.argmax(numpy.absolute(stack), axis=0)
>>> ind
array([0, 1, 1, 1])
So now I have the indices I need, but how to apply this to the stacked array? If I just index stack by ind, numpy is doing something broadcasting stuff I don't need:
>>> stack[ind]
array([[ 4, 1, 2, 3],
[ 0, -5, 6, 7],
[ 0, -5, 6, 7],
[ 0, -5, 6, 7]])
What I want to get is array([4, -5, 6, 7])
Or to ask from a slightly different perspective: How do I get the array numpy.amax(stack, axis=0) based on the indices returned by numpy.argmax(stack, axis=0)?
The stacking operation would be inefficient. We can simply use np.where to do the choosing based on the absolute valued comparisons -
In [198]: a
Out[198]: array([4, 1, 2, 3])
In [199]: b
Out[199]: array([ 0, -5, 6, 7])
In [200]: np.where(np.abs(a) > np.abs(b), a, b)
Out[200]: array([ 4, -5, 6, 7])
This works on generic n-dim arrays without any modification.
If you have 2D numpy ndarray, classical indexing no longer applies. So to achieve what you want, to avoid brodcatsting, you have to index with 2D array too:
>>> stack[[ind,np.arange(stack.shape[1])]]
array([ 4, -5, 6, 7])
For 'normal' Python:
>>> a=[[1,2],[3,4]]
>>> b=[0,1]
>>> [x[y] for x,y in zip(a,b)]
[1, 4]
Perhaps it can be applied to arrays too, I am not familiar enough with Numpy.
Find array of max and min and combine using where
maxs = np.amax(stack, axis=0)
mins = np.amin(stack, axis=0)
max_abs = np.where(np.abs(maxs) > np.abs(mins), maxs, mins)

Effective way to find and delete certain elements from a numpy array

I have a numpy array with some positive numbers and some -1 elements. I want to find these elements with -1 values, delete them and store their indeces.
One way of doing it is iterating through the array and cheking if the value is -1. Is this the only way? If not, what about its effectivness? Isn't there a more effective python tool then?
With numpy.argwhere() and numpy.delete() routines:
import numpy as np
arr = np.array([1, 2, 3, -1, 4, -1, 5, 10, -1, 14])
indices = np.argwhere(arr == -1).flatten()
new_arr = np.delete(arr, indices)
print(new_arr) # [ 1 2 3 4 5 10 14]
print(indices.tolist()) # [3, 5, 8]
https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.argwhere.html
https://docs.scipy.org/doc/numpy/reference/generated/numpy.delete.html
import numpy as np
yourarray=np.array([4,5,6,7,-1,2,3,-1,9,-1]) #say
rangenumpyarray=np.arange(len(yourarray)) # to create a column adjacent to your array of range
arra=np.hstack((rangenumpyarray.reshape(-1,1),yourarray.reshape(-1,1))) # combining both arrays as two columns
arra[arra[:,1]==-1][:,0] # learn boolean indexing
Use a combination of np.flatnonzero and simple boolean indexing.
x = array([ 0, 0, -1, 0, 0, -1, 0, -2, 0, 0])
m = x != -1 # generate a mask
idx = np.flatnonzero(~m)
x = x[m]
idx
array([2, 5])
x
array([ 0, 0, 0, 0, 0, -2, 0, 0])

Slice an array starting from first nonzero element

I have an array with leading zeros, and I want the array from the first nonzero element.
For example, I have an array
x=[0,0,0,0,0,3,2,0,0,4,5]
I want to obtain :
x=[3,2,0,0,4,5]
What you have is a list, not an array. This is a pure-Python solution, though you might consider converting your list into a NumPy array and going with the Divakar's solution for better performance (if and only if you plan on using NumPy for downstream processing)
In [1]: from itertools import dropwhile
In [2]: from operator import not_
In [3]: x = [0,0,0,0,0,3,2,0,0,4,5]
In [4]: list(dropwhile(not_, x))
Out[4]: [3, 2, 0, 0, 4, 5]
Use np.argmax on non-zeros to get the starting non-zero index and then simply slice it -
x[(x!=0).argmax():]
Sample run -
In [71]: x
Out[71]: array([0, 0, 0, 0, 0, 3, 2, 0, 0, 4, 5])
In [72]: x[(x!=0).argmax():]
Out[72]: array([3, 2, 0, 0, 4, 5])

Can python itertools.imap(func,p,q) work with a conditional test on the index (e.g. to get elements with odd indexes only)?

I have the following arrays
>>> a
array([0, 8, 0, 8, 0, 8])
>>> b
array([0, 6, 0, 6, 0, 6])
these represent the real and imaginary parts of a set of complex numbers.
I can reformat them into numpy.complex datatype using the following
>>> [x for x in itertools.imap(complex,a,b)]
[0j, (8+6j), 0j, (8+6j), 0j, (8+6j)]
However what I really want to get is only the elements with odd indexes:
[(8+6j),(8+6j),(8+6j)]
Is there an easy way to achieve this?
>>> import numpy as np
>>> a = np.array([0, 8, 0, 8, 0, 8])
>>> b = np.array([0, 6, 0, 6, 0, 6])
>>> np.vectorize(complex)(a, b)[1::2]
array([ 8.+6.j, 8.+6.j, 8.+6.j])
That would be the best way but just for completeness, the itertools solution would be:
>>> from itertools import imap, islice
>>> list(islice(imap(complex,a,b), 1, None, 2))
[(8+6j), (8+6j), (8+6j)]
[1::2] takes every other item, starting on index 1 (the second), to the end of the list. That is:
>>> [x for x in itertools.imap(complex,a,b)][1::2]
[(8+6j), (8+6j), (8+6j)]

Categories

Resources