I have an array that represents distances, so I try to get an array with the indexes from the 3 smaller and increasing distances, this way:
array([[ 2.8],
[ 206. ],
[ 84.4],
[ 297.6],
[ 112.7],
[ 235.4],
[ 170.7],
[ 22.2],
[ 264.1],
[ 163.2],
[ 43.7],
[ 131.2]])
Result = [0, 7, 10]
Any idea o suggestion? Thanks in advance.
I found a not very elegant but working approach. If someone has another fast or better version, will be welcome.
from operator import itemgetter
# b distances array
b = [i for i in enumerate(b)]
b = sorted(b, key=itemgetter(1))
b = [i[0] for i in b]
result = b[:3]
result
# [0,7,10]
Related
Hi guys how would I go on converting numpy arrays as such:
[[ 8.82847075 -5.70925653]
[ 1.07032615 -1.77975378]
[-10.41163742 -0.33042086]
[ 0.23799394 5.5978591 ]
[ 7.7386861 -4.16523845]]
To what I desire in Python 3.10. That includes having the keys and values rounded to the nearest integer:
{'9':-6, '1':-2, '-10':0, '0':6, '8':-4}
The following should work
a = np.round(a)
d = dict(zip(a[:, 0].astype(str), a[:, 1]))
Note: Equal keys will merge.
dict(zip(*d.round().astype(int).T))
Out: {9: -6, 1: -2, -10: 0, 0: 6, 8: -4}
The data
d = np.array([[ 8.82847075, -5.70925653],
[ 1.07032615, -1.77975378],
[-10.41163742, -0.33042086],
[ 0.23799394, 5.5978591 ],
[ 7.7386861 , -4.16523845]])
You can convert array to dictionary without any external library.
this method uses list comprehension:
assuming input array is in_array and the output dictionary is out_dict
out_dict = {int(x[0]):int(x[1]) for x in in_array}
I have an array of 2D, called X and a 1D array for X's classes, what i want to do is slice the same amount of first N percent elements for each class and store inside a new array, for example, in a simple way without doing for loops:
For the following X array which is 2D:
[[0.612515 0.385088 ]
[0.213345 0.174123 ]
[0.432596 0.8714246]
[0.700230 0.730789 ]
[0.455105 0.128509 ]
[0.518423 0.295175 ]
[0.659871 0.320614 ]
[0.459677 0.940614 ]
[0.823733 0.831789 ]
[0.236175 0.10750 ]
[0.379032 0.241121 ]
[0.512535 0.8522193]
Output is 3.
Then, i'd like to store the first 3 index that belongs to class 0 and first 3 elements that belongs to class 0 and maintain the occurence order of the indices, the following output:
First 3 from each class:
[1 0 0 1 0 1]
New_X =
[[0.612515 0.385088 ]
[0.213345 0.174123 ]
[0.432596 0.8714246]
[0.700230 0.730789 ]
[0.455105 0.128509 ]
[0.518423 0.295175 ]]
First, 30% is only 2 elements from each class (even when using np.ceil).
Second, I'll assume both arrays are numpy.array.
Given the 2 arrays, we can find the desired indices using np.where and array y in the following way:
in_ = sorted([x for x in [*np.where(y==0)[0][:np.ceil(0.3*6).astype(int)],*np.where(y==1)[0][:np.ceil(0.3*6).astype(int)]]]) # [0, 1, 2, 3]
Now we can simply slice X like so:
X[in_]
# array([[0.612515 , 0.385088 ],
# [0.213345 , 0.174123 ],
# [0.432596 , 0.8714246],
# [0.70023 , 0.730789 ]])
The definition of X and y are:
X = np.array([[0.612515 , 0.385088 ],
[0.213345 , 0.174123 ],
[0.432596 , 0.8714246],
[0.70023 , 0.730789 ],
[0.455105 , 0.128509 ],
[0.518423 , 0.295175 ],
[0.659871 , 0.320614 ],
[0.459677 , 0.940614 ],
[0.823733 , 0.831789 ],
[0.236175 , 0.1075 ],
[0.379032 , 0.241121 ],
[0.512535 , 0.8522193]])
y = np.array([1, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0])
Edit
The following line: np.where(y==0)[0][:np.ceil(0.3*6).astype(int)] doing the following:
np.where(y==0)[0] - returns all the indices where y==0
Since you wanted only the 30%, we slice those indices to get all the values up to 30% - [:np.ceil(0.3*6).astype(int)]
I have got a 3d array (an array of triangles). I would like to get the triangles (2d arrays) containing a given point (1d array).
I went through in1d, where, argwhere but I am still unsuccessfull....
For instance with :
import numpy as np
import numpy.random as rd
t = rd.random_sample((10,3,3))
v0 = np.array([1,2,3])
t[1,2] = v0
t[5,0] = v0
t[8,1] = v0
I would like to get:
array([[[[[ 0.87312 , 0.33411403, 0.56808291],
[ 0.36769417, 0.66884858, 0.99675896],
[ 1. , 2. , 3. ]],
[[ 0.31995867, 0.58351034, 0.38731405],
[ 1. , 2. , 3. ],
[ 0.04435288, 0.96613852, 0.83228402]],
[[ 1. , 2. , 3. ],
[ 0.28647107, 0.95755263, 0.5378722 ],
[ 0.73731078, 0.8777235 , 0.75866665]]]])
to then get the set of v0 adjacent points
{[ 0.87312 , 0.33411403, 0.56808291],
[ 0.36769417, 0.66884858, 0.99675896],
[ 0.31995867, 0.58351034, 0.38731405],
[ 0.04435288, 0.96613852, 0.83228402],
[ 0.28647107, 0.95755263, 0.5378722 ],
[ 0.73731078, 0.8777235 , 0.75866665]}
without looping, the array being quite big.
For instance
In [28]: np.in1d(v0,t[8]).all()
Out[28]: True
works as a test on a line, but I can't get it over the all array.
Thanks for your help.
What I mean is the vectorized equivalent to:
In[54]:[triangle for triangle in t if v0 in triangle ]
Out[54]:
[array([[ 0.87312 , 0.33411403, 0.56808291],
[ 0.36769417, 0.66884858, 0.99675896],
[ 1. , 2. , 3. ]]),
array([[ 0.31995867, 0.58351034, 0.38731405],
[ 1. , 2. , 3. ],
[ 0.04435288, 0.96613852, 0.83228402]]),
array([[ 1. , 2. , 3. ],
[ 0.28647107, 0.95755263, 0.5378722 ],
[ 0.73731078, 0.8777235 , 0.75866665]])]
You can simply do -
t[(t==v0).all(axis=-1).any(axis=-1)]
We are performing ALL and ANY reduction along the last axis with axis=-1 there. First .all(axis=-1) looks for rows exactly matching the array v0 and then the latter .any(axis=-1) looks for ANY match in each of the 2D blocks. This results in a boolean array of the same length as the length of input array. So, we use the boolean array to filter out valid elements off the input array.
I have a 2D numpy array called 'subset':
array([[ 0.00000000e+00, 2.46951219e-03, 4.93902439e-03],
[ inf, 4.04938272e+02, 2.02469136e+02],
[ 1.77635684e-14, 4.49872050e+01, 1.05094837e+01],
[ 4.33257766e-16, 1.09724890e+00, 2.56328871e-01],
[ 4.85082380e-32, 3.11123702e-01, 1.69792239e-02]])
I'm trying to sort by array 2 (3rd array) in descending order. The following works for ascending order:
>>> subset[:,subset[2,:].argsort()]
array([[ 0.00000000e+00, 4.93902439e-03, 2.46951219e-03],
[ inf, 2.02469136e+02, 4.04938272e+02],
[ 1.77635684e-14, 1.05094837e+01, 4.49872050e+01],
[ 4.33257766e-16, 2.56328871e-01, 1.09724890e+00],
[ 4.85082380e-32, 1.69792239e-02, 3.11123702e-01]])
As you can see, the 3rd array is sorted by increasing order, and the other rows get sorted the same way, preserving the columns as intended.
But when I try to reverse this sorting by doing the same operation on the negative array (thinking it should produce the mirror image of the prior result), it doesn't work as intended.
>>> subset[:,-subset[2,:].argsort()]
array([[ 0.00000000e+00, 2.46951219e-03, 4.93902439e-03],
[ inf, 4.04938272e+02, 2.02469136e+02],
[ 1.77635684e-14, 4.49872050e+01, 1.05094837e+01],
[ 4.33257766e-16, 1.09724890e+00, 2.56328871e-01],
[ 4.85082380e-32, 3.11123702e-01, 1.69792239e-02]])
Why doesn't this work?
The reason it doesn't work is, of course, operator precedence. A pair of parentheses and it does what you want:
subset[:,(-subset[2,:]).argsort()]
# array([[ 2.46951219e-03, 4.93902439e-03, 0.00000000e+00],
# [ 4.04938272e+02, 2.02469136e+02, inf],
# [ 4.49872050e+01, 1.05094837e+01, 1.77635684e-14],
# [ 1.09724890e+00, 2.56328871e-01, 4.33257766e-16],
# [ 3.11123702e-01, 1.69792239e-02, 4.85082380e-32]])
But note that simple reversal is typically faster:
timeit(lambda: subset[:,(-subset[2,:]).argsort()])
# 2.9420917620009277
timeit(lambda: subset[:,subset[2,:].argsort()[::-1]])
# 2.556215071992483
Hello I'm new to python and vectorization.
Say you have a 5x3 numpy array like this:
array([[ -1.262, -4.034, 2.422],
[ 13.849, 14.377, 4.951],
[ 3.203, 10.209, -2.865],
[ 3.618, -3.51 , -7.059],
[ -0.098, -5.012, 6.389]])
and you want to end up with a new 5x2 matrix with minima removed from each inner dimension like this:
array([[ -1.262, 2.422],
[ 13.849, 14.377],
[ 3.203, 10.209],
[ 3.618, -3.51 ],
[ -0.098, 6.389]])
What is the best way to achieve that? I suppose it is with vectorization?
Thank you!
I would think there's a relatively straightforward function for this, but it may not be around in numpy; pandas could probably do this more easily.
With numpy, this is one way to do this:
In [56]: a = np.array([[ -1.262, -4.034, 2.422],
[ 13.849, 14.377, 4.951],
[ 3.203, 10.209, -2.865],
[ 3.618, -3.51 , -7.059],
[ -0.098, -5.012, 6.389]])
In [57]: m = np.argmin(a, axis=1)
In [58]: indices = np.ones(shape=a.shape, dtype=bool)
In [59]: indices[np.arange(5), m] = False
In [60]: a[indices].reshape((-1, a.shape[1]-1))
Out[60]:
array([[ -1.262, 2.422],
[ 13.849, 14.377],
[ 3.203, 10.209],
[ 3.618, -3.51 ],
[ -0.098, 6.389]])
The step with the boolean indices is to "invert" the indices returned from np.argmin, since the latter returns integer indices, not boolean indices.