Вместо изменения superArray
вы можете использовать np.quantile
. np.median(x)
совпадает с np.quantile(x,1/2)
. Если вы пропустите два наименьших элемента, вы сдвинете среднюю точку на 1, то есть вы можете использовать np.quantile(superArray,1/2+1/(superArray.size-1)
# compute reference value for validation
ref = np.median(np.partition(superArray.ravel(),2)[2:])
# quantile method
np.quantile(superArray,1/2+1/(superArray.size-1)) == ref
# True
np.quantile
и np.median
, оба немного медленные, вы можете получитьповышение производительности благодаря использованию np.partition
вместо:
# do-it-yourself quantile
idx = np.arange((superArray.size+1)//2,(superArray.size+2)//2+1)
np.partition(superArray,idx,axis=None)[idx].mean() == ref
#True
Время:
def f():
idx = np.arange((superArray.size+1)//2,(superArray.size+2)//2+1)
return np.partition(superArray,idx,axis=None)[idx].mean()
def g():
return np.quantile(superArray,1/2+1/(superArray.size-1))
def h():
return np.median(np.partition(superArray.ravel(),2)[2:])
def i():
return np.median(np.sort(superArray.ravel())[2:])
for tag,fn in [('partition',f),('quantile',g),('median+part',h),('median+sort',i)]:
print(f'{tag:20s} {timeit(fn,number=100000)*10:.4f} us')
# partition 14.5955 us
# quantile 96.5980 us
# median+part 30.1133 us
# median+sort 29.4419 us
То же самое для большего размера (1000x1000) superArray
:
partition 12.2952 ms
quantile 12.7227 ms
median+part 20.8914 ms
median+sort 87.3877 ms