import numpy as np
def argmedian(x):
return np.argpartition(x, len(x) // 2)[len(x) // 2]
# Works for odd-length arrays, where the median is in the array:
x = np.random.rand(101)
print("median in array:", np.median(x) in x)
# median in array: True
print(x[argmedian(x)], np.median(x))
# 0.5819150016674371 0.5819150016674371
# Doesn't work for even-length arrays, where the median is not in the array:
x = np.random.rand(100)
print("median in array:", np.median(x) in x)
# median in array: False
print(x[argmedian(x)], np.median(x))
# 0.6116799104572843 0.6047559243909065
随着数组大小的增加,这比公认的基于排序的解决方案快得多:
x = np.random.rand(1000)
%timeit np.argsort(x)[len(x)//2]
# 10000 loops, best of 3: 25.4 µs per loop
%timeit np.argpartition(x, len(x) // 2)[len(x) // 2]
# 100000 loops, best of 3: 6.03 µs per loop
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'))
7条答案
按热度按时间dfddblmv1#
一个快速的近似:
ryevplcw2#
一般来说,这是一个不适定的问题,因为数组不一定包含numpy定义的中位数。例如:
但是当数组的长度是奇数时,中位数通常会在数组中,因此要求其索引确实有意义:
对于奇数长度数组,确定中值索引的有效方法是使用
np.argpartition
函数。例如:随着数组大小的增加,这比公认的基于排序的解决方案快得多:
wj8zmpe13#
这似乎是一个老问题,但我找到了一个很好的方法来使它:
这里的巧妙技巧是最近插值的百分位内置选项,它从列表中返回一个“真实的”的中值,因此之后搜索它是安全的。
kuhbmx9i4#
您可以保留元素索引(
zip
)并排序并返回中间的元素或中间的两个元素,但排序将是O(n.logn)
。下面的方法在时间复杂度方面是O(n)
。输出:
这个想法是,如果只有一个中位数(数组有奇数长度),那么它返回中位数的索引。如果我们需要对元素求平均值(数组的长度是偶数),那么它将返回列表中这两个元素的索引。
d5vmydt95#
可接受的答案
numpy.argsort(data)[len(data)//2]
的问题在于它只适用于一维数组。对于n维数组,我们需要使用不同的解决方案,该解决方案基于@Hagay提出的答案。camsedfj6#
接受的答案
numpy.argsort(data)[len(data)//2]
不能处理带有NaN的数组。对于二维数组,要获取轴中的中值列索引=1(沿着行):
由于这是一个偶数列的4*4数组,因此第3行的中值的列索引应该是6,而不是76。
7nbnzgx97#
这是一个修改@jakevdp的答案,它也有一个可选的轴输入,以沿着特定轴获取argmedian: