eya*_*ler 11
快速近似:
numpy.argsort(data)[len(data)//2]
Run Code Online (Sandbox Code Playgroud)
小智 7
这似乎是一个古老的问题,但我发现了一个很好的方法:
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'))
Run Code Online (Sandbox Code Playgroud)
这里的巧妙技巧是最近插值的百分位内置选项,它从列表中返回"实际"中值,因此之后搜索它是安全的.
一般来说,这是一个不适定的问题,因为对于 numpy 的中位数定义,数组不一定包含自己的中位数。例如:
>>> np.median([1, 2])
1.5
Run Code Online (Sandbox Code Playgroud)
但是当数组的长度为奇数时,中位数通常会在数组中,因此要求其索引确实有意义:
>>> np.median([1, 2, 3])
2
Run Code Online (Sandbox Code Playgroud)
对于奇数长度数组,确定中值索引的一种有效方法是使用该np.argpartition函数。例如:
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
Run Code Online (Sandbox Code Playgroud)
随着数组大小的增长,这比公认的基于排序的解决方案要快得多:
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
Run Code Online (Sandbox Code Playgroud)