2017-06-28 5 views
2

Ich habe einen Datenrahmen und ich würde gerne np.where verwenden, um bestimmte Elemente basierend auf einer bestimmten Bedingung zu finden, und dann pd.drop verwenden, um die entsprechenden Elemente zu löschen zum Index gefunden mit np.where.Pandas Datenrahmen verwenden np.where und drop zusammen

D.h.

idx_to_drop = np.where(myDf['column10'].isnull() | myDf['column14'].isnull()) 
myDf.drop(idx_to_drop) 

Aber ich bekomme einen Wert Fehler, da Tropfen nicht numpy Array-Indizes dauert. Gibt es eine Möglichkeit dies zu erreichen, indem np.where und einige Drop-Funktionen in Pandas verwendet werden?

+1

Can‘ t tust du nur: 'mask = myDf ['column10']. isnull() | myDf ['column14']. isnull() 'und dann' myDf [~ mask] '? – Divakar

+0

@Divakar vielen Dank! Ich könnte, ich suchte auch nach einer Möglichkeit, np zu verwenden, wo es sehr flexibel in Bezug auf Operationen ist, die ich tun könnte. Ich persönlich mag auch gerne, welche Indizes ich lösche. Nichtsdestotrotz ist dies mehr ein Wunsch als nötig, denn Maske sieht gut aus! – Dnaiel

Antwort

3

Es gibt zwei gängige Muster, das zu erreichen:


die Zeilen aus, die Ihren „Abwurf nicht erfüllen "Bedinge oder negiere deine Bedingungen und wähle diejenigen Zeilen aus, die diese Bedingungen erfüllen - @jezrael has provided a good example for that approach.


die Zeilen Drop "Abwurf" Bedingungen erfüllen:

df = df.drop(np.where(df['column10'].isnull() | df['column14'].isnull())[0]) 

Timing-: erster Ansatz scheint etwas schneller zu sein:

Setup:

df = pd.DataFrame(np.random.rand(100,5), columns=list('abcde')) 
df.loc[::7, ::2] = np.nan 
df = pd.concat([df] * 10**4, ignore_index=True) 

In [117]: df.shape 
Out[117]: (1000000, 5) 

In [118]: %timeit df[~(df['a'].isnull() | df['e'].isnull())] 
10 loops, best of 3: 46.6 ms per loop 

In [119]: %timeit df[df['a'].notnull() & df['e'].notnull()] 
10 loops, best of 3: 39.9 ms per loop 

In [120]: %timeit df.drop(np.where(df['a'].isnull() | df['e'].isnull())[0]) 
10 loops, best of 3: 65.5 ms per loop 

In [122]: %timeit df.drop(np.where(df[['a','e']].isnull().any(1))[0]) 
10 loops, best of 3: 97.1 ms per loop 

In [123]: %timeit df[df[['a','e']].notnull().all(1)] 
10 loops, best of 3: 72 ms per loop 
+0

Maxu Sind Sie sicher? 'Es gibt zwei übliche Muster, um das zu erreichen:'? Ich denke, Drop-Methode ist hier langsamer und nicht zu empfehlen. Kannst du ein paar Timings hinzufügen? Ich bin jetzt offline, nur am Telefon, also kann ich es nicht tun. – jezrael

+0

@jezrael, ich werde versuchen, ein Timing hinzuzufügen ... – MaxU

+1

Genau. Boolesche Indexierung ist am schnellsten. – jezrael

2

Ich glaube, Sie boolean indexing mit inversem Zustand müssen durch ~, isnull und | (bitweise or):

print (~(myDf['column10'].isnull() | myDf['column14'].isnull())) 
0 False 
1  True 
2 False 
dtype: bool 

myDf[~(myDf['column10'].isnull() | myDf['column14'].isnull())] 

Probe:

myDf = pd.DataFrame({'column10':[np.nan, 1,5], 'column14':[np.nan, 1,np.nan]}) 
print (myDf) 
    column10 column14 
0  NaN  NaN 
1  1.0  1.0 
2  5.0  NaN 

myDf = myDf[~(myDf['column10'].isnull() | myDf['column14'].isnull())] 
print (myDf) 
    column10 column14 
1  1.0  1.0 

Lösung mit notnull und & (bitweise and)

myDf = myDf[myDf['column10'].notnull() & myDf['column14'].notnull()] 
print (myDf) 
    column10 column14 
1  1.0  1.0 

andere Lösungen mit any oder all:

myDf = myDf[~myDf[['column10', 'column14']].isnull().any(axis=1)] 
print (myDf) 
    column10 column14 
1  1.0  1.0 

myDf = myDf[myDf[['column10', 'column14']].notnull().all(axis=1)] 
print (myDf) 
    column10 column14 
1  1.0  1.0 
Verwandte Themen