2016-05-19 1 views
1

Возможно ли получить результат как numpy.argmin, так и numpy.amin с одним вызовом numpy? Благодарю.Эффективное получение numpy.argmin и numpy.amin в то же время

+0

что не так с его вызовом по отдельным строкам или через запятую? – EdChum

+0

хорошо. Я думал, есть ли одна проверка массива, которая может делать как argmin, так и amin. Проверка массива один раз для argmin, а затем еще раз для amin, кажется, тратит время. Или делать это на самом деле медленнее? – rxu

ответ

4

Вы можете использовать np.argmin для получения индексов, соответствующих минимальным значениям, а затем использовать их с NumPy's advanced indexing для получения минимальных значений.

Возьмем массив 2D, чтобы продемонстрировать использование. Пусть A будет массивом 2D и предположим, что нас интересует поиск минимальных индексов и значений вдоль axis=1.

Таким образом, мы можем сделать -

min_idx = np.argmin(A,axis=1) 
min_val = A[np.arange(A.shape[0]),min_idx] 

Давайте рассмотрим фактический 2D массив для образца запуска и проверки результатов -

In [16]: A 
Out[16]: 
array([[79, 97, 12, 54, 59], 
     [44, 45, 42, 78, 32], 
     [32, 41, 67, 60, 4], 
     [24, 4, 85, 94, 65]]) 

In [17]: min_idx = np.argmin(A,axis=1) 

In [18]: A[np.arange(A.shape[0]),min_idx] # Using min_idx & indexing 
Out[18]: array([12, 32, 4, 4]) 

In [19]: np.amin(A,axis=1)    # Using np.amin to verify 
Out[19]: array([12, 32, 4, 4]) 

Продолжительность испытания -

In [26]: def original_app(A): 
    ...:  min_idx = np.argmin(A,axis=1) 
    ...:  min_val = np.amin(A,axis=1) 
    ...:  return min_idx, min_val 
    ...: 
    ...: def proposed_app(A): 
    ...:  min_idx = np.argmin(A,axis=1) 
    ...:  min_val = A[np.arange(A.shape[0]),min_idx] 
    ...:  return min_idx, min_val 
    ...: 

In [27]: A = np.random.randint(0,99,(4000,5000)) 

In [28]: %timeit original_app(A) 
10 loops, best of 3: 70.9 ms per loop 

In [29]: %timeit proposed_app(A) 
10 loops, best of 3: 33.1 ms per loop 

Остановимся кт таймингов немного больше -

In [31]: min_idx = np.argmin(A,axis=1) 

In [32]: %timeit np.argmin(A,axis=1)    # Used in both methods 
10 loops, best of 3: 34.5 ms per loop 

In [33]: %timeit np.amin(A,axis=1)    # Original approach 
10 loops, best of 3: 37.3 ms per loop 

In [34]: %timeit A[np.arange(A.shape[0]),min_idx] # Proposed approach 
10000 loops, best of 3: 56 µs per loop 

Как мы видим большую прибыль с продвинутой индексацией на последнем этапе с ничтожным выполнением, затраченного на него. Это позволяет почти 100% сработать с ним!

+0

Я тоже думал об этом. может сделать некоторые сроки позже. – rxu

+0

@rxu Добавлены тайминги для случая «2D» с формой '(4000 500)'. – Divakar