I'am using numpy and have an array (ndarray type) which contain some values. Shape of this array 1000x1500. I reshaped it
brr = np.reshape(arr, arr.shape[0]*arr.shape[1])
when I trying
brr.reverse()
AttributeError: ‘numpy.ndarray’ object has no attribute ‘reverse’
get error.
How I can sort this array ?
If you just want to reverse it:
brr[:] = brr[::-1]
Actually, this reverses along axis 0. You could also revert on any other axis, if the array has more than one.
To sort in reverse order:
>>> arr = np.random.random((1000,1500))
>>> brr = np.reshape(arr, arr.shape[0]*arr.shape[1])
>>> brr.sort()
>>> brr = brr[::-1]
>>> brr
array([ 9.99999960e-01, 9.99998167e-01, 9.99998114e-01, ...,
3.79672182e-07, 3.23871190e-07, 8.34517810e-08])
or, using argsort:
>>> arr = np.random.random((1000,1500))
>>> brr = np.reshape(arr, arr.shape[0]*arr.shape[1])
>>> sort_indices = np.argsort(brr)[::-1]
>>> brr[:] = brr[sort_indices]
>>> brr
array([ 9.99999849e-01, 9.99998950e-01, 9.99998762e-01, ...,
1.16993050e-06, 1.68760770e-07, 6.58422260e-08])
Try this for sorting in descending order ,
import numpy as np
a = np.array([1,3,4,5,6])
print -np.sort(-a)
To sort a 1d array in descending order, pass reverse=True to sorted.
As #Erik pointed out, sorted will first make a copy of the list and then sort it in reverse.
import numpy as np
import random
x = np.arange(0, 10)
x_sorted_reverse = sorted(x, reverse=True)
Related
i have a numpy ndarray which looks like this
np.array(
[[40.26164428, 63.50590524, 58.30951895],
[50.99019514, 69.0651866 , 60.44005295],
[20.24845673, 14.31782106, 58.52349955],
[54.58937626, 53.03772242, 21.09502311],
[56.75385449, 57.5847202 , 1.41421356]])
(NOTE: the arrays i generate are always in different shapes ( the shape of this array is (5, 3) but it can be (2, 2) (4, 1)... ),
so this isn't a 3D coordinates array, it just generated like that)
What i need is to find the two closest values of the generated array and return their indices, in this case the values are 58.30951895 and 58.52349955, which should return the coordinates [0, 2] and [2, 2]
I've tried to use cKDtree but this isn't a coordinate array so that doesn't work in this case, how should i do this?
I'm going to be embarrassed when someone points out a one-liner, but here's a way to do it.
I flatten the array, then sort it, then find the deltas between each element. Find the minimum delta. Now, from the sorted array, I know the values of the two closest elements. argwhere then gives me the coordinates.
import numpy as np
data = np.array(
[[40.26164428, 63.50590524, 58.30951895],
[50.99019514, 69.0651866 , 60.44005295],
[20.24845673, 14.31782106, 58.52349955],
[54.58937626, 53.03772242, 21.09502311],
[56.75385449, 57.5847202 , 1.41421356]])
order = np.sort(data.reshape(-1))
delta = np.diff(order)
am = np.argmin(delta)
print( np.argwhere(data == order[am]))
print( np.argwhere(data == order[am+1]))
Output:
C:\tmp>python x.py
[[0 2]]
[[2 2]]
If I understand it correctly their position in the array is irrelevant, so in that case is simple, put the numbers in a list in a way that it remember their original position, then sorted it and find the lowest difference between two consecutive elements
>>> import itertools
>>> def pairwise(iterable):
a,b = itertools.tee(iterable)
next(b,None)
return zip(a,b)
>>> data=[[40.26164428, 63.50590524, 58.30951895],
[50.99019514, 69.0651866, 60.44005295],
[20.24845673, 14.31782106, 58.52349955],
[54.58937626, 53.03772242, 21.09502311],
[56.75385449, 57.5847202, 1.41421356]]
>>> linear=[ (value,x,y) for x,row in enumerate(data) for y,value in enumerate(row)]
>>> linear.sort(key=lambda x:x[0])
>>> min(pairwise(linear),key=lambda pair: abs(pair[0][0]-pair[1][0]))
((58.30951895, 0, 2), (58.52349955, 2, 2))
>>>
I have following column names in a list:
vars = ['age','balance','day','duration','campaign','pdays','previous','job_admin.','job_blue-collar']
I have one array which consists of array indexes
(array([1, 5, 7], dtype=int64),)
I want to subset the list based on array indexes
Desired output should be
vars = ['balance','pdays','job_admin.']
I have tried something like this in python
for i, a in enumerate(X):
if i in new_L:
print i
But,it does not work.
Simply use a loop to do that:
result=[]
for i in your_array:
result.append(vars[i])
or one linear
[vars[i] for i in your_array]
If you're using numpy anyway, use its advanced indexing
import numpy as np
vars = ['age','balance','day','duration','campaign','pdays',
'previous','job_admin.','job_blue-collar']
indices = (np.array([1, 5, 7]),)
sub_array = np.asarray(vars)[indices]
# --> array(['balance', 'pdays', 'job_admin.'], dtype='<U15')
or if you want a list
sub_list = np.asarray(vars)[indices].tolist()
# --> ['balance', 'pdays', 'job_admin.']
index = [1, 5, 7]
vars = [vars[i] for i in index]
If I understand correctly, your data are:
vars = ['age','balance','day','duration','campaign','pdays','previous','job_admin.','job_blue-collar']
and indexes are:
idx = [1, 5, 7]
Then you can do:
>>> [vars[i] for i in idx]
['balance', 'pdays', 'job_admin.']
You can use operator.itemgetter:
>>> import numpy as np
>>> import operator
>>> vars = ['age','balance','day','duration','campaign','pdays','previous','job_admin.','job_blue-collar']
>>> idx = np.array([1,5,7])
>>> operator.itemgetter(*idx)(vars)
('balance', 'pdays', 'job_admin.'
This is actually the fastest solution posted so far.
>>> from timeit import repeat
>>> kwds = dict(globals=globals(), number=1000000)
>>>
>>> repeat("np.asarray(vars)[idx]", **kwds)
[2.2382465780247003, 2.225632123881951, 2.1969433058984578]
>>> repeat("[vars[i] for i in idx]", **kwds)
[0.9384958958253264, 0.9366465201601386, 0.9373494561295956]
>>> repeat("operator.itemgetter(*idx)(vars)", **kwds)
[0.9045725339092314, 0.9015877249184996, 0.9032398068811744]
Interestingly, it becomes more than twice as fast if we convert idx to a list first, and that's including the cost of conversion:
>>> repeat("operator.itemgetter(*idx.tolist())(vars)", **kwds)
[0.4062491739168763, 0.4086623480543494, 0.4049343201331794]
We can also afford to convert the result to list and still are much faster than all the other solutions:
>>> repeat("list(operator.itemgetter(*idx.tolist())(vars))", **kwds)
[0.561687784967944, 0.5593925788998604, 0.5586365279741585]
I have a list like this:
myList = [10,30,40,20,50]
Now I use numpy's argsort function to get the indices for the sorted list:
import numpy as np
so = np.argsort(myList)
which gives me the output:
array([0, 3, 1, 2, 4])
When I want to sort an array using so it works fine:
myArray = np.array([1,2,3,4,5])
myArray[so]
array([1, 4, 2, 3, 5])
But when I apply it to another list, it does not work but throws an error
myList2 = [1,2,3,4,5]
myList2[so]
TypeError: only integer arrays with one element can be converted to an
index
How can I now use so to sort another list without using a for-loop and without converting this list to an array first?
myList2 is a normal python list, and it does not support that kind of indexing.
You would either need to convert that to a numpy.array , Example -
In [8]: np.array(myList2)[so]
Out[8]: array([1, 4, 2, 3, 5])
Or you can use list comprehension -
In [7]: [myList2[i] for i in so]
Out[7]: [1, 4, 2, 3, 5]
You can't. You have to convert it to an array then back.
myListSorted = list(np.array(myList)[so])
Edit: I ran some benchmarks comparing the NumPy way to the list comprehension. NumPy is ~27x faster
>>> from timeit import timeit
>>> import numpy as np
>>> myList = list(np.random.rand(100))
>>> so = np.argsort(myList) #converts list to NumPy internally
>>> timeit(lambda: [myList[i] for i in so])
12.29590070003178
>>> myArray = np.random.rand(100)
>>> so = np.argsort(myArray)
>>> timeit(lambda: myArray[so])
0.42915570305194706
I have a numpy array like this:
a = [0,88,26,3,48,85,65,16,97,83,91]
How can I get the values at certain index positions in ONE step? For example:
ind_pos = [1,5,7]
The result should be:
[88,85,16]
Just index using you ind_pos
ind_pos = [1,5,7]
print (a[ind_pos])
[88 85 16]
In [55]: a = [0,88,26,3,48,85,65,16,97,83,91]
In [56]: import numpy as np
In [57]: arr = np.array(a)
In [58]: ind_pos = [1,5,7]
In [59]: arr[ind_pos]
Out[59]: array([88, 85, 16])
The one liner "no imports" version
a = [0,88,26,3,48,85,65,16,97,83,91]
ind_pos = [1,5,7]
[ a[i] for i in ind_pos ]
Although you ask about numpy arrays, you can get the same behavior for regular Python lists by using operator.itemgetter.
>>> from operator import itemgetter
>>> a = [0,88,26,3,48,85,65,16,97,83,91]
>>> ind_pos = [1, 5, 7]
>>> print itemgetter(*ind_pos)(a)
(88, 85, 16)
You can use index arrays, simply pass your ind_pos as an index argument as below:
a = np.array([0,88,26,3,48,85,65,16,97,83,91])
ind_pos = np.array([1,5,7])
print(a[ind_pos])
# [88,85,16]
Index arrays do not necessarily have to be numpy arrays, they can be also be lists or any sequence-like object (though not tuples).
your code would be
a = [0,88,26,3,48,85,65,16,97,83,91]
ind_pos = [a[1],a[5],a[7]]
print(ind_pos)
you get [88, 85, 16]
So i have a particular array, that has 2 seperate arrays withing itself. What I am looking to do is to average together those 2 seperate arrays, so for instance, if i have my original array such as [(2,3,4),(4,5,6)] and I want an output array like [3,5], how would i do this? My attempt to do this is as follows:
averages = reduce(sum(array)/len(array), [array])
>>> map(lambda x: sum(x)/len(x), [(2,3,4),(4,5,6)])
[3, 5]
reduce is not a good choice here. Just use a list comprehension:
>>> a = [(2,3,4),(4,5,6)]
>>> [sum(t)/len(t) for t in a]
[3, 5]
Note that / is integer division by default in python2.
If you have numpy available, you have a nicer option:
>>> import numpy as np
>>> a = np.array(a)
>>> a.mean(axis=1)
array([ 3., 5.])
You can do this with a list comphrehesion:
data = [(2,3,4),(4,5,6)]
averages = [ sum(tup)/len(tup) for tup in data ]