This question already has an answer here:
Numpy binary matrix - get rows and columns of True elements
(1 answer)
Closed 2 years ago.
I have a large set of data and I am trying to get it into a specific form (So i can re-use someone else's code). Here's an example of a smaller set I am working with.
>>> a = np.array([[0, 1, 2], [0, 2, 4], [0, 3, 6]])
>>> a
array([[0, 1, 2],
[0, 2, 4],
[0, 3, 6]])
>>> np.where(a==0)
(array([0, 1, 2]), array([0, 0, 0]))
So, what this returns is two arrays in a tuple.
The places that are 0 are (0,0), (1,0), and (2,0)
I'd like to get this data into this form:
[(0,0), (1,0), (2,0)]
Which is a list of tuples.
Appreciate any pointers.
Try numpy.argwhere
[tuple(x) for x in numpy.argwhere(a==0)]
list(zip(*np.where(a==0)))
How this works:
The zip function will produce a sequence of tuples, consisting of:
tuple containing element 0 from each of its arguments
tuple containing element 1 from each of its arguments
... etc..
So the elements of this sequence will be in the required form if the arguments to zip are the elements of the tuple returned by numpy.where. The use of * means to expand this tuple to separate positional parameters, as required, rather than passing in the tuple itself. It is then only necessary to call list() to iterate over the iterator returned by zip and convert the values into a list.
Example:
>>> a = np.array([[0, 1, 2], [0, 2, 4], [0, 3, 6]]) # array in the question
>>> list(zip(*np.where(a==0)))
[(0, 0), (1, 0), (2, 0)] # list of 2-tuples
>>> a = a.reshape(1,3,3) # now a 3d-array (adds slowest varying dimension of size 1)
>>> list(zip(*np.where(a==0)))
[(0, 0, 0), (0, 1, 0), (0, 2, 0)] # now you get a list of 3-tuples
You need this:
np.argwhere(a==0)
output for your example:
[[0 0]
[1 0]
[2 0]]
And if you need a list of tuples instead:
list(map(tuple,np.argwhere(a==0)))
output:
[(0, 0), (1, 0), (2, 0)]
Related
I want to cast set in list to list like below.
before: [(1, 1, 1), (1, 1, 0), (1, 0, 1)]
after: [[1, 1, 1], [1, 1, 0], [1, 0, 1]]
I need the as simple code as possible.
>>> x = [(1, 1, 1), (1, 1, 0), (1, 0, 1)]
>>> list(map(list, x))
[[1, 1, 1], [1, 1, 0], [1, 0, 1]]
Explanation
map(list, x) takes an iterable x and applies function list to each element of this iterable. Thus the tuple (1, 1, 1) becomes the list [1, 1, 1], (1, 1, 0) becomes [1, 1, 0] and (1, 0, 1) becomes [1, 0, 1].
These lists are then stored in a map object (assuming Python 3.x). A map object is an iterator, which can be converted to a list by calling list on it, as shown above. Often, though, you don't need to make this explicit conversion because iterator allows you to traverse the elements directly:
>>> for elem in map(list, x):
... print(elem)
...
[1, 1, 1]
[1, 1, 0]
[1, 0, 1]
Let's define "before" as a variable called "array". Then we take the for-loop of the "array" while casting each element to a list.
array = [(1,1,1), (1,1,0), (1,0,1)]
casted_array = []
for tuples in array:
casted_array.append(list(tuples))
There are slightly easier ways to do this, but they are harder to understand. Explanation: You define the list [(1,1,1), (1,1,0), (1,0,1)] as a variable and then define a "dummy" variable called "casted_array". You then loop through the items in the "array" variable while saving them to the "tuples" iteration variable. Every time the iteration cycle loops, the sets/tuples are converted into lists and then added on to the "casted_array" variable. The casted set/tuple is now stored in the "casted_array" variable.
I have a series of n 2D arrays that are presented to a function as a 3D array of depth n. I want to generate a tuple of each set of values along the third axis, then replace each of these tuples with a single index value and a lookup table.
I'm working in python, with some large datasets so it needs to be scalable, so will probably use numpy. Other solutions are accepted though.
Here's what I've got so far:
In [313]: arr=np.array([[[0,0,0],[1,2,2],[3,0,0]],[[0,1,0],[1,3,2],[0,0,0]]])
In [314]: stacked = np.stack((arr[0], arr[1]), axis=2)
In [315]: pairs = stacked.reshape(-1, arr.shape[0])
In [316]: pairs
Out[316]:
array([[0, 0],
[0, 1],
[0, 0],
[1, 1],
[2, 3],
[2, 2],
[3, 0],
[0, 0],
[0, 0]])
In [317]: unique = set([tuple(a) for a in pairs])
In [318]: lookup = sorted(list(unique))
In [319]: lookup
Out[319]: [(0, 0), (0, 1), (1, 1), (2, 2), (2, 3), (3, 0)]
Now, I want to create an output array, using the indexes of the values in the lookup table, so the output would be:
[0, 1, 0, 2, 4, 3, 5, 0, 0]
This example is just with two input 2D arrays, but there could be many more.
So, I've come up with a solution that produces the outputs I want, but is it the most efficient method of doing this? In particular, the lookup.index call is a bit costly. Does anyone have a better way?
def squash_array(arr):
tuples = arr.T.reshape(-1, arr.shape[0])
lookup = sorted(list(set([tuple(a) for a in tuples])))
out_arr = np.array([lookup.index(tuple(a)) for a in tuples]).reshape(arr.shape[1:][::-1]).T
return out_arr, lookup
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
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)]
I'm aware of numpy.argsort(), but what it does is return indices of elements in an array that would be sorted along a certain axis.
What I need is to sort all the values in an N-dimensional array and have a linear list of tuples as as result.
Like this:
>>> import numpy
>>> A = numpy.array([[7, 8], [9, 5]])
>>> numpy.magic(A)
[(1, 0), (0, 1), (0, 0), (1, 1)]
P.S. I don't even understand what the output of argsort is trying to tell me for this array.
np.argsort(A) is sorting each row of A separately. For example,
In [21]: np.argsort([[6,5,4],[3,2,1]])
Out[21]:
array([[2, 1, 0],
[2, 1, 0]])
Instead, you want to flatten your array into a 1-dimensional array of values, then argsort that. That can be done by setting the axis parameter to None (thanks to #Akavall for pointing this out):
In [23]: np.argsort(A, axis=None)
Out[23]: array([3, 0, 1, 2])
Then use np.unravel_index to recover the associated index in A.
In [14]: import numpy as np
In [15]: A = np.array([[7, 8], [9, 5]])
In [4]: np.column_stack(np.unravel_index(np.argsort(A, axis=None)[::-1], A.shape))
Out[4]:
array([[1, 0],
[0, 1],
[0, 0],
[1, 1]])
Note, for NumPy version 1.5.1 or older, np.unravel_index raises a ValueError if passed an array-like object for its first argument. In that case, you could use a list comprehension:
In [17]: [np.unravel_index(p, A.shape) for p in np.argsort(A, axis=None)[::-1]]
Out[17]: [(1, 0), (0, 1), (0, 0), (1, 1)]