2016-07-30 14 views
1

Beginnend mit dem folgenden ArrayWählen Sie Werte aus einem Array basiert auf einem Booleschen Ausdruck auf einem anderen Array angewendet

array([ nan, nan, nan, 1., nan, nan, 0., nan, nan]) 

, die wie so erzeugt:

import numpy as np 
row = np.array([ np.nan, np.nan, np.nan, 1., np.nan, np.nan, 0., np.nan, np.nan]) 

Ich möchte die Indizes erhalten des sortierten Arrays und schließen Sie dann die nans aus. In diesem Fall möchte ich [6,3] erhalten.

Ich habe mit der folgenden Art und Weise kommen, dies zu tun:

vals = np.sort(row) 
inds = np.argsort(row) 

def select_index_by_value(indices, values): 
    selected_indices = [] 
    for i in range(len(indices)): 
     if not np.isnan(values[i]): 
      selected_indices.append(indices[i]) 
    return selected_indices 

selected_inds = select_index_by_value(inds, vals) 

Jetzt selected_inds ist [6,3]. Dies scheint jedoch ein paar Zeilen Code zu sein, um etwas Einfaches zu erreichen. Gibt es dafür vielleicht einen kürzeren Weg?

Antwort

1

Eine weitere Option:

row.argsort()[~np.isnan(np.sort(row))] 
# array([6, 3]) 
+0

Beide Lösungen funktionieren, aber ich finde die Verwendung von booleschen Indizierung eleganter als Numpy 'wo'. Vielen Dank! –

3

Man könnte so etwas tun -

# Store non-NaN indices 
idx = np.where(~np.isnan(row))[0] 

# Select non-NaN elements, perform argsort and use those argsort  
# indices to re-order non-NaN indices as final output 
out = idx[row[idx].argsort()] 
0

Es gibt eine andere schnellere Lösung (für OP-Daten).

Psidom Solution

%timeit row.argsort()[~np.isnan(np.sort(row))] 

The slowest run took 31.23 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 8.16 µs per loop 

Divakar Solution

%timeit idx = np.where(~np.isnan(row))[0]; idx[row[idx].argsort()] 

The slowest run took 35.11 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 4.73 µs per loop 

Basierend auf Divakar Solution

%timeit np.where(~np.isnan(row))[0][::-1] 

The slowest run took 9.42 times longer than the fastest. This could mean that an intermediate result is being cached. 
100000 loops, best of 3: 2.86 µs per loop 

Ich denke, das funktioniert, weil np.where(~np.isnan(row)) Auftrag behält.

Verwandte Themen