Suppose you have an unsorted list and you sort it using np.sort. Is there a way to get the indices of the sorted list from the original list using numpy?
The easiest way is to augment the array with the position indices and then sort the 2-D array. That gives you both the sorted data and its original position indicies at the same time.
If you only want the indicies (not the sorted data), the use argsort:
>>> from numpy import array
>>> arr = array([10, 5, 80, 20, 70, 18])
>>> arr.argsort()
array([1, 0, 5, 3, 4, 2])
Related
This question is probably basic for some of you but it I am new to Python. I have an initial array:
initial_array = np.array ([1, 6, 3, 4])
I have another array.
value_array= np.array ([10, 2, 3, 15])
I want an array called output array which looks at the values in value_array and reorder the initial array.
My result should look like this:
output_array = np.array ([4, 1, 3, 6])
Does anyone know if this is possible to do in Python?
So far I have tried:
for i in range(4):
find position of element
You can use numpy.argsort to find sort_index from value_array then rearrange the initial_array base sort_index in the reversing order with [::-1].
>>> idx_sort = value_array.argsort()
>>> initial_array[idx_sort[::-1]]
array([4, 1, 3, 6])
You could use stack to put arrays together - basically adding column to initial array, then sort by that column.
import numpy as np
initial_array = np.array ([1, 6, 3, 4])
value_array = np.array ([10, 2, 3, 15])
output_array = np.stack((initial_array, value_array), axis=1)
output_array=output_array[output_array[:, 1].argsort()][::-1]
print (output_array)
[::-1] part is for descending order. Remove to get ascending.
I am assuming initial_array and values_array will have same length.
I'd like to generate an array which contains the positions of the highest integers/floating point numbers to the lowest in another array.
For example:
integers = [1,6,8,5]
I want the newly generated array to be:
newArray = [2,1,3,0]
or
floatingPoints = [1.6,0.5,1.1]
would become
newArray = [0,2,1]
You can use the numpy function argsort and then simply reverse the ordering as it gives you ascending rather than descending, by default:
np.argsort(integers)[::-1]
Example:
import numpy as np
integers = np.array([1, 6, 8, 5])
np.argsort(integers)[::-1]
This results in the desired [2, 1, 3, 0].
The elements inside each array in the sample_array represents the index. How do I change these elements such that the results is similar to final_array?
sample_array = [np.array([5, 3, 2]), np.array([4, 0, 1, 6])
sample_list = [element_0, element_1, element_2, element_3, element_4, element_5, element_6]
final_array = [np.array([element_5, element_3, element_2]), np.array([element_4, element_0, element_1, element_6])
You can change the list to a numpy array and then use your indices:
sample_array = [np.array([5, 3, 2]), np.array([4, 0, 1, 6])]
sample_list = np.array(['element_0', 'element_1', 'element_2', 'element_3', 'element_4', 'element_5', 'element_6'])
sample_list = np.array(sample_list)
print([sample_list[sa] for sa in sample_array])
[array(['element_5', 'element_3', 'element_2'], dtype='<U9'),
array(['element_4', 'element_0', 'element_1', 'element_6'], dtype='<U9')]
You can do this with the following:
np.array([[sample_list[i] for i in row] for row in sample_array])
See np.array's documentation for more details.
Another idea would be to marry the list comprehension and itemgetter. We need to use itemgetter instead of a normal slice operator since we want to extract elements from a list with arbitrary indices, as per your input:
# sample inputs
In [18]: sample_arr = [np.array([5, 3, 2]), np.array([4, 0, 1, 6])]
In [19]: sample_list = [10, 11, 12, 13, 14, 15, 16]
In [20]: from operator import itemgetter
We use a single list comprehension where we iterate over the items in the sample_arr list and use itemgetter for slicing. That would return a callable, to which we pass the list from which the elements need to be picked up (i.e. sample_list). Finally, we need to wrap the result in np.array() since you need a list of arrays, similar to the input.
final_array = [np.array(itemgetter(*arr.tolist())(sample_list)) for arr in sample_arr]
In [22]: final_array
Out[22]: [array([15, 13, 12]), array([14, 10, 11, 16])]
I have a tuple of arrays and need to find the length of an array by using the index of the tuple. This tuple is generated from a sparse matrix alternative to numpy where i'm using scipy.sparse.csr_matrix and numpy.unravel_index based on this post
ie:
>>>T = [(array([0,1,2,3,4,5]),), (array([0,1,2,3,4,5,6,7,8,9]),)]
>>>print(T[1])
(array([0,1,2,3,4,5,6,7,8,9]),)
I need to find the length of each array within the tuple for use later. using len() does not work
>>>len(T[1])
1
I am using this within a for loop that iterates through each array using those arrays as an index for other data.
I have searched and searched for how to solve this but found nothing. Please help!
Each item in T is a tuple of length 1, so just index it, like this:
>>> len(T[1][0])
10
To be clear:
>>> T[1]
(array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),)
>>> T[1][0]
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
You can try comprehension concept as well,like
arr_length = [len(i[0]) for i in T]
Apologies if this has already been asked, but I searched quite a bit and couldn't find quite the right solution. I'm new to python, but I'll try to be as clear as possible. In short, I have a list of arrays in the following format resulting from a joining a multiprocessing pool:
array = [[[1,2,3], 5, 47, 2515],..... [[4,5,6], 3, 35, 2096]]]
and I want to get all values from the first array element to form a new array in the following form:
print(new_array)
[1,2,3,4,5,6]
In my code, I was trying to get the first value through this function:
new_array = array[0][0]
but this only returns the first value as such:
print(new_array)
[1,2,3]
I also tried np.take after converting the array into a np array:
array = np.array(array)
new_array = np.take(results,0)
print(new_array)
[1,2,3]
I have tried a number of np functions (concatenate, take, etc.) to try and iterate this over the list, but get back the following error (presumably because the size of the array changes):
ValueError: autodetected range of [[], [1445.0, 1445.0, -248.0, 638.0, -108.0, 649.0]] is not finite
Thanks for any help!
You can achieve it without numpy using reduce:
from functools import reduce
l = [[[1,2,3], 5, 47, 2515], [[4,5,6], 3, 35, 2096]]
res = reduce(lambda a, b: [*a, *b], [x[0] for x in l])
Output
[1, 2, 3, 4, 5, 6]
Maybe it is worth mentioning that [*a, *b] is a way to concatenate lists in python, for example:
[*[1, 2, 3], *[4, 5, 6]] # [1, 2, 3, 4, 5, 6]
You could also use itertools' chain() function to flatten an extraction of the first subArray in each element of the list:
from itertools import chain
result = list(chain(*[sub[0] for sub in array]))