Is there a way to get the median index in python in one command?

Is there something like numpy.argmin(x) but for the median?

+11
source share
4 answers

quick approach:

 numpy.argsort(data)[len(data)//2] 
+9
source

It seems like an old question, but I found a good way to do it like this:

 import random import numpy as np #some random list with 20 elements a = [random.random() for i in range(20)] #find the median index of a medIdx = a.index(np.percentile(a,50,interpolation='nearest')) 

A nice trick here is the percentile option for the closest interpolation, which returns the "real" median value from the list, so it's safe to look after it later.

+6
source

You can save indexes with elements ( zip ) and sort and return the element in the middle or two elements in the middle, however the sort will be O(n.logn) . The following method is O(n) in terms of time complexity.

 import numpy as np def arg_median(a): if len(a) % 2 == 1: return np.where(a == np.median(a))[0][0] else: l,r = len(a) // 2 - 1, len(a) // 2 left = np.partition(a, l)[l] right = np.partition(a, r)[r] return [np.where(a == left)[0][0], np.where(a == right)[0][0]] print(arg_median(np.array([ 3, 9, 5, 1, 15]))) # 1 3 5 9 15, median=5, index=2 print(arg_median(np.array([ 3, 9, 5, 1, 15, 12]))) # 1 3 5 9 12 15, median=5,9, index=2,1 

Output:

 2 [2, 1] 

The idea is that if there is only one median (the array has an odd length), then it returns the median index. If we need to perform averaging over elements (the array has an even length), it returns the indices of these two elements in the list.

+1
source

The problem with the accepted answer numpy.argsort(data)[len(data)//2] is that it works only for one-dimensional arrays. For n-dimensional arrays we need to use another solution based on the answer suggested by @Hagay.

 import numpy as np # Initialize random 2d array, a a = np.random.randint(0, 7, size=16).reshape(4,4) array([[3, 1, 3, 4], [5, 2, 1, 4], [4, 2, 4, 2], [6, 1, 0, 6]]) # Get the argmedians np.stack(np.nonzero(a == np.percentile(a,50,interpolation='nearest')), axis=1) array([[0, 0], [0, 2]]) # Initialize random 3d array, a a = np.random.randint(0, 10, size=27).reshape(3,3,3) array([[[3, 5, 3], [7, 4, 3], [8, 3, 0]], [[2, 6, 1], [7, 8, 8], [0, 6, 5]], [[0, 7, 8], [3, 1, 0], [9, 6, 7]]]) # Get the argmedians np.stack(np.nonzero(a == np.percentile(a,50,interpolation='nearest')), axis=1) array([[0, 0, 1], [1, 2, 2]]) 
0
source

Source: https://habr.com/ru/post/1232859/


All Articles