import numpy as np
from scipy import signal
y = np.array([[2, 1, 2, 3, 2, 0, 1, 0],
[2, 1, 2, 3, 2, 0, 1, 0]])
maximas = signal.argrelmax(y, axis=1)
print maximas
(array([0, 0, 1, 1], dtype=int64), array([3, 6, 3, 6], dtype=int64))
The maximas produced the index of tuples: (0,3) and (0,6) are for row one [2, 1, 2, 3, 2, 0, 1, 0]; and (1,6) and (1,6) are for another row [2, 1, 2, 3, 2, 0, 1, 0].
The following prints all the results, but I want to extract only the first maxima of both rows, i.e., [3,3] using the tuples. So, the tuples I need are (0,3) and (1,3).
How can I extract them from the array of tuples, i.e., 'maximas'?
>>> print y[kk]
[3 1 3 1]
Given the tuple maximas, here's one possible NumPy way:
>>> a = np.column_stack(maximas)
>>> a[np.unique(a[:,0], return_index=True)[1]]
array([[0, 3],
[1, 3]], dtype=int64)
This stacks the coordinate lists returned by signal.argrelmax into an array a. The return_index parameter of np.unique is used to find the first index of each row number. We can then retrieve the relevant rows from a using these first indexes.
This returns an array, but you could turn it into a list of lists with tolist().
To return the first column index of the maximum in each row, you just need to take the indices returned by np.unique from maximas[0] and use them to index maximas[1]. In one line, it's this:
>>> maximas[1][np.unique(maximas[0], return_index=True)[1]]
array([3, 3], dtype=int64)
To retrieve the corresponding values from each row of y, you can use np.choose:
>>> cols = maximas[1][np.unique(maximas[0], return_index=True)[1]]
>>> np.choose(cols, y.T)
array([3, 3])
Well, a pure Python approach will be to use itertools.groupby(group on the row's index) and a list comprehension:
>>> from itertools import groupby
>>> from operator import itemgetter
>>> [max(g, key=lambda x: y[x])
for k, g in groupby(zip(*maximas), itemgetter(0))]
[(0, 3), (1, 3)]
Related
>>> ndarr = np.array([0, 1, 2])
>>> (lambda x: x + 1) (ndarr)
array([1, 2, 3])
I see that it replaces every element with the function applied to it.
but when I do this to a two dimensional array:
>>> ndarr = np.array([[0, 1, 2], [3, 4, 5]])
>>> (lambda x: x[0]) (ndarr)
array([0, 1, 2])
I thought this would take the two elements of the array which are [0, 1, 2] and [3, 4, 5], apply the lambda to them resulting in 0 and 3, and the result would be [0, 3]. but this applies the function to the whole array instead. why? and wat do I do to get [0, 3]?
Applying + 1 on a numpy array will cause all elements to be incremented by one, as you have noticed.
However, this does not imply that every operation you perform using a numpy array will be a "mapping". In the second example, there is simply a nested list, and you select the first element of the outer list. The exact same would happen if you just used regular Python:
>>> nlist = [[0, 1, 2], [3, 4, 5]]
>>> (lambda x: x[0]) (nlist)
[0, 1, 2]
You are looking for a mapping if you want to apply an operation on each of the nested arrays. However, this problem can be solved with a slice most easily:
>>> ndarr = np.array([[0, 1, 2], [3, 4, 5]])
>>> ndarr[:,0]
array([0, 3])
Suppose I have a numpy array
a = np.array([0,2,3,4,5,1,9,0,0,7,9,0,0,0]).reshape(7,2)
I want to find out the indices of all the times the minimum element (here 0) occurs in the 2nd column. Using argmin I can find out the index of when 0 is occurring for the first time. How can I do this in Python?
Using np.flatnonzero on a[:, 1]==np.min(a) is the most starightforward way:
In [3]: idxs = np.flatnonzero(a[:, 1]==np.min(a))
In [4]: idxs
Out[4]: array([3, 5, 6])
After you reshaped your array it looks like this:
array([[0, 2],
[3, 4],
[5, 1],
[9, 0],
[0, 7],
[9, 0],
[0, 0]])
You can get all elements that are of the same value by using np.where. IN your case the following would work:
np.where(a.T[-1] == a.argmin())
# This would give you (array([3, 5, 6]),)
What happens here is that you create a transposed view on the array. This means you can easily access the columns. The term view here means that the a array itself is not changed for that. This leaves you with:
a.T
array([[0, 3, 5, 9, 0, 9, 0],
[2, 4, 1, 0, 7, 0, 0]])
From this you select the last line (i.e. the last column of a) by using the index -1. Now you have the array
array([2, 4, 1, 0, 7, 0, 0])
on which you can call np.where(condititon), which gives you all indices for which the condition is true. In your case the condition is
a.T[-1] == a.argmin()
which gives you all entries in the selected line of the transposed array that have the same value as np.argmin(a) which, as you said, is 0 in your case.
This question already has an answer here:
Pythonic way for numpy array of array (with index of rows)
(1 answer)
Closed 5 years ago.
I have a 2x3 array like the following:
import numpy as np
y = np.array([[1,2,3], [4,5,6]])
I want to index one element from each column. For example, the 1st element in column 1, the 2nd element in column 2, and the 1st element in column 3. The output should look like this:
ans = [1,5,3]
I tried to use
y[0,1,0]
and
np.take(y, [0,1,0,1], axis=1)
but neither worked. Can you help?
In [448]: y = np.array([[1,2,3], [4,5,6]])
In [450]: idx = [0,1,0]
idx selects the row for successive columns, so you need to pair it with a column indexing list (or array):
In [454]: y[idx,[0,1,2]]
Out[454]: array([1, 5, 3])
In [455]: y[idx, np.arange(y.shape[1])]
Out[455]: array([1, 5, 3])
It may help to visualize this by taking the 'transpose' of the 2 lists:
In [456]: list(zip([0,1,0],[0,1,2]))
Out[456]: [(0, 0), (1, 1), (0, 2)]
In [457]: [y[i,j] for i,j in Out[456]]
Out[457]: [1, 5, 3]
You'd have to do it this way with lists, but numpy does the pairing for you.
you should access it this way :
>>> y
array([[1, 2, 3],
[4, 5, 6]])
>>> y[0,0]
1
>>> y[1,1]
5
>>> y[0,2]
3
>>> [y[0,0], y[1,1],y[0,2]]
[1, 5, 3]
numpy array is reference with coordinates [x,y] in your array.
Then you can find some strategy to solve a specific problem, with a specific logic :
>>> y
array([[1, 2, 3],
[4, 5, 6]])
>>> res=[y[j%2,j] for j in range(y.shape[1])]
>>> res
[1, 5, 3]
>>> y = np.array([[1,1,1,1,1,1,1,1],[4,5,6,7,8,9,10,11]])
>>> res=[y[j%2,j] for j in range(y.shape[1])]
>>> res
[1, 5, 1, 7, 1, 9, 1, 11]
EDIT :
>>> idxCol=[0,1,0]
>>> res=[y[idxCol[i],i] for i in range(len(idxCol))]
>>> res
[1, 5, 3]
Hi I have a list flat which is length 2800, it contains 100 results for each of 28 variables: Below is an example of 4 results for 2 variables
[0,
0,
1,
1,
2,
2,
3,
3]
I would like to reshape the list to an array (2,4) so that the results for each variable are in a single element.
[[0,1,2,3],
[0,1,2,3]]
You can think of reshaping that the new shape is filled row by row (last dimension varies fastest) from the flattened original list/array.
If you want to fill an array by column instead, an easy solution is to shape the list into an array with reversed dimensions and then transpose it:
x = np.reshape(list_data, (100, 28)).T
Above snippet results in a 28x100 array, filled column-wise.
To illustrate, here are the two options of shaping a list into a 2x4 array:
np.reshape([0, 0, 1, 1, 2, 2, 3, 3], (4, 2)).T
# array([[0, 1, 2, 3],
# [0, 1, 2, 3]])
np.reshape([0, 0, 1, 1, 2, 2, 3, 3], (2, 4))
# array([[0, 0, 1, 1],
# [2, 2, 3, 3]])
You can specify the interpretation order of the axes using the order parameter:
np.reshape(arr, (2, -1), order='F')
Step by step:
# import numpy library
import numpy as np
# create list
my_list = [0,0,1,1,2,2,3,3]
# convert list to numpy array
np_array=np.asarray(my_list)
# reshape array into 4 rows x 2 columns, and transpose the result
reshaped_array = np_array.reshape(4, 2).T
#check the result
reshaped_array
array([[0, 1, 2, 3],
[0, 1, 2, 3]])
The answers above are good. Adding a case that I used.
Just if you don't want to use numpy and keep it as list without changing the contents.
You can run a small loop and change the dimension from 1xN to Nx1.
tmp=[]
for b in bus:
tmp.append([b])
bus=tmp
It maybe not efficient in case of very large numbers. But it works for small set of numbers.
Thanks
I went through these threads:
Find unique rows in numpy.array
Removing duplicates in each row of a numpy array
Pandas: unique dataframe
and they all discuss several methods for computing the matrix with unique rows and columns.
However, the solutions look a bit convoluted, at least to the untrained eye. Here is for example top solution from the first thread, which (correct me if I am wrong) I believe it is the safest and fastest:
np.unique(a.view(np.dtype((np.void, a.dtype.itemsize*a.shape[1])))).view(a.dtype).reshape(-1,
a.shape[1])
Either way, the above solution only returns the matrix of unique rows. What I am looking for is something along the original functionality of np.unique
u, indices = np.unique(a, return_inverse=True)
which returns, not only the list of unique entries, but also the membership of each item to each unique entry found, but how can I do this for columns?
Here is an example of what I am looking for:
array([[0, 2, 0, 2, 2, 0, 2, 1, 1, 2],
[0, 1, 0, 1, 1, 1, 2, 2, 2, 2]])
We would have:
u = array([0,1,2,3,4])
indices = array([0,1,0,1,1,3,4,4,3])
Where the different values in u represent the set of unique columns in the original array:
0 -> [0,0]
1 -> [2,1]
2 -> [0,1]
3 -> [2,2]
4 -> [1,2]
First lets get the unique indices, to do so we need to start by transposing your array:
>>> a=a.T
Using a modified version of the above to get unique indices.
>>> ua, uind = np.unique(np.ascontiguousarray(a).view(np.dtype((np.void,a.dtype.itemsize * a.shape[1]))),return_inverse=True)
>>> uind
array([0, 3, 0, 3, 3, 1, 4, 2, 2, 4])
#Thanks to #Jamie
>>> ua = ua.view(a.dtype).reshape(ua.shape + (-1,))
>>> ua
array([[0, 0],
[0, 1],
[1, 2],
[2, 1],
[2, 2]])
For sanity:
>>> np.all(a==ua[uind])
True
To reproduce your chart:
>>> for x in range(ua.shape[0]):
... print x,'->',ua[x]
...
0 -> [0 0]
1 -> [0 1]
2 -> [1 2]
3 -> [2 1]
4 -> [2 2]
To do exactly what you ask, but will be a bit slower if it has to convert the array:
>>> b=np.asfortranarray(a).view(np.dtype((np.void,a.dtype.itemsize * a.shape[0])))
>>> ua,uind=np.unique(b,return_inverse=True)
>>> uind
array([0, 3, 0, 3, 3, 1, 4, 2, 2, 4])
>>> ua.view(a.dtype).reshape(ua.shape+(-1,),order='F')
array([[0, 0, 1, 2, 2],
[0, 1, 2, 1, 2]])
#To return this in the previous order.
>>> ua.view(a.dtype).reshape(ua.shape + (-1,))
Essentially, you want np.unique to return the indexes of the unique columns, and the indices of where they're used? This is easy enough to do by transposing the matrix and then using the code from the other question, with the addition of return_inverse=True.
at = a.T
b = np.ascontiguousarray(at).view(np.dtype((np.void, at.dtype.itemsize * at.shape[1])))
_, u, indices = np.unique(b, return_index=True, return_inverse=True)
With your a, this gives:
In [35]: u
Out[35]: array([0, 5, 7, 1, 6])
In [36]: indices
Out[36]: array([0, 3, 0, 3, 3, 1, 4, 2, 2, 4])
It's not entirely clear to me what you want u to be, however. If you want it to be the unique columns, then you could use the following instead:
at = a.T
b = np.ascontiguousarray(at).view(np.dtype((np.void, at.dtype.itemsize * at.shape[1])))
_, idx, indices = np.unique(b, return_index=True, return_inverse=True)
u = a[:,idx]
This would give
In [41]: u
Out[41]:
array([[0, 0, 1, 2, 2],
[0, 1, 2, 1, 2]])
In [42]: indices
Out[42]: array([0, 3, 0, 3, 3, 1, 4, 2, 2, 4])
Not entirely sure what you are after, but have a look at the numpy_indexed package (disclaimer: I am its author); it is sure to make problems of this kind easier:
import numpy_indexed as npi
unique_columns = npi.unique(A, axis=1)
# or perhaps this is what you want?
unique_columns, indices = npi.group_by(A.T, np.arange(A.shape[1])))