Как удалить 2 самых низких значения в ndarray? - PullRequest
1 голос
/ 11 октября 2019

Я начал с массива:

np.random.seed(959)
superArray = np.random.randint(101, size=(5,3))

Мне нужно вычислить медиану superArray после удаления 2 самых маленьких значений.

Кажется, я не могу найти какие-либо методыдля удаления значений, которые работают с ndarrays. Приведенный ниже код - это то, что, как я думал, может быть.

np.median(superArray.delete(superArray,[min(superArray),min(superArray)]))

Конечно, это выдало мне ошибку, потому что delete не является методом для типа ndarray, но это то, к чему я стремился.

Ответы [ 3 ]

1 голос
/ 11 октября 2019

вы можете np.partition и ravel. np.partition будет быстрее, чем вся сортировка в больших массивах

np.random.seed(959)
superArray = np.random.randint(101, size=(5,3))
np.partition(superArray.ravel(), 2)[2:]
1 голос
/ 11 октября 2019

Вместо изменения 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
1 голос
/ 11 октября 2019

Вам не обязательно удалять или удалять что-либо. Вы можете просто работать с видом массива, который не включает элементы, которые вам не нужны. Самый простой способ сделать это с нарезкой. Таким образом, вы можете привести их в порядок и пропустить первые два, например

np.median(np.sort(superArray.ravel())[2:])

. Вам нужно ravel(), чтобы сгладить массив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...