it-swarm.com.de

So löschen Sie Zeilen von Pandas DataFrame, deren Wert in einer bestimmten Spalte NaN ist

Ich habe dieses DataFrame und möchte nur die Datensätze, deren EPS -Spalte nicht NaN ist:

>>> df
                 STK_ID  EPS  cash
STK_ID RPT_Date                   
601166 20111231  601166  NaN   NaN
600036 20111231  600036  NaN    12
600016 20111231  600016  4.3   NaN
601009 20111231  601009  NaN   NaN
601939 20111231  601939  2.5   NaN
000001 20111231  000001  NaN   NaN

... d.h. So etwas wie df.drop(....), um diesen resultierenden Datenrahmen zu erhalten:

                  STK_ID  EPS  cash
STK_ID RPT_Date                   
600016 20111231  600016  4.3   NaN
601939 20111231  601939  2.5   NaN

Wie mache ich das?

612
bigbug

Nicht drop. Nehmen Sie einfach Zeilen, in denen EPSendlich ist:

import numpy as np

df = df[np.isfinite(df['EPS'])]
491
eumiro

Diese Frage ist bereits gelöst, aber ...

... betrachten Sie auch die von Wouter vorgeschlagene Lösung in sein ursprünglicher Kommentar . Die Fähigkeit, mit fehlenden Daten, einschließlich dropna(), umzugehen, ist explizit in pandas integriert. Abgesehen von der potenziell verbesserten Leistung im Vergleich zur manuellen Ausführung bieten diese Funktionen auch eine Vielzahl von Optionen, die nützlich sein können.

In [24]: df = pd.DataFrame(np.random.randn(10,3))

In [25]: df.iloc[::2,0] = np.nan; df.iloc[::4,1] = np.nan; df.iloc[::3,2] = np.nan;

In [26]: df
Out[26]:
          0         1         2
0       NaN       NaN       NaN
1  2.677677 -1.466923 -0.750366
2       NaN  0.798002 -0.906038
3  0.672201  0.964789       NaN
4       NaN       NaN  0.050742
5 -1.250970  0.030561 -2.678622
6       NaN  1.036043       NaN
7  0.049896 -0.308003  0.823295
8       NaN       NaN  0.637482
9 -0.310130  0.078891       NaN

In [27]: df.dropna()     #drop all rows that have any NaN values
Out[27]:
          0         1         2
1  2.677677 -1.466923 -0.750366
5 -1.250970  0.030561 -2.678622
7  0.049896 -0.308003  0.823295

In [28]: df.dropna(how='all')     #drop only if ALL columns are NaN
Out[28]:
          0         1         2
1  2.677677 -1.466923 -0.750366
2       NaN  0.798002 -0.906038
3  0.672201  0.964789       NaN
4       NaN       NaN  0.050742
5 -1.250970  0.030561 -2.678622
6       NaN  1.036043       NaN
7  0.049896 -0.308003  0.823295
8       NaN       NaN  0.637482
9 -0.310130  0.078891       NaN

In [29]: df.dropna(thresh=2)   #Drop row if it does not have at least two values that are **not** NaN
Out[29]:
          0         1         2
1  2.677677 -1.466923 -0.750366
2       NaN  0.798002 -0.906038
3  0.672201  0.964789       NaN
5 -1.250970  0.030561 -2.678622
7  0.049896 -0.308003  0.823295
9 -0.310130  0.078891       NaN

In [30]: df.dropna(subset=[1])   #Drop only if NaN in specific column (as asked in the question)
Out[30]:
          0         1         2
1  2.677677 -1.466923 -0.750366
2       NaN  0.798002 -0.906038
3  0.672201  0.964789       NaN
5 -1.250970  0.030561 -2.678622
6       NaN  1.036043       NaN
7  0.049896 -0.308003  0.823295
9 -0.310130  0.078891       NaN

Es gibt auch andere Optionen (siehe docs unter http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html ), einschließlich des Ablegens von Spalten anstelle von Zeilen.

Ziemlich praktisch!

771
Aman

Ich weiß, dass dies bereits beantwortet wurde, aber nur um eine reine pandas Lösung für diese spezielle Frage zu finden, im Gegensatz zu der allgemeinen Beschreibung von Aman (die wunderbar war) und für den Fall, dass jemand anderes darauf reagiert:

import pandas as pd
df = df[pd.notnull(df['EPS'])]
97
Kirk Hadley

Sie können dies verwenden:

df.dropna(subset=['EPS'], how='all', inplace = True)
37
Joe

Einfachste aller Lösungen:

filtered_df = df[df['EPS'].notnull()]

Die obige Lösung ist viel besser als die Verwendung von np.isfinite ()

28
Gil Baggio

Sie können die DataFrame-Methode notnull oder die Inverse von isnull oder numpy.isnan verwenden:

In [332]: df[df.EPS.notnull()]
Out[332]:
   STK_ID  RPT_Date  STK_ID.1  EPS  cash
2  600016  20111231    600016  4.3   NaN
4  601939  20111231    601939  2.5   NaN


In [334]: df[~df.EPS.isnull()]
Out[334]:
   STK_ID  RPT_Date  STK_ID.1  EPS  cash
2  600016  20111231    600016  4.3   NaN
4  601939  20111231    601939  2.5   NaN


In [347]: df[~np.isnan(df.EPS)]
Out[347]:
   STK_ID  RPT_Date  STK_ID.1  EPS  cash
2  600016  20111231    600016  4.3   NaN
4  601939  20111231    601939  2.5   NaN
21

sie können dropna verwenden

Beispiel

Löschen Sie die Zeilen, in denen mindestens ein Element fehlt.

df=df.dropna()

Definieren Sie, in welchen Spalten nach fehlenden Werten gesucht werden soll.

df=df.dropna(subset=['column1', 'column1'])

Siehe this für weitere Beispiele

Hinweis: Der Achsenparameter von dropna ist seit Version 0.23.0 veraltet:

12
Umer

noch eine andere Lösung, die die Tatsache nutzt, dass np.nan != np.nan:

In [149]: df.query("EPS == EPS")
Out[149]:
                 STK_ID  EPS  cash
STK_ID RPT_Date
600016 20111231  600016  4.3   NaN
601939 20111231  601939  2.5   NaN
10
MaxU

Oder (mit isnull auf NaNs prüfen und dann ~ verwenden, um das Gegenteil zu No NaNs zu erzielen):

df=df[~df['EPS'].isnull()]

Jetzt:

print(df)

Ist:

                 STK_ID  EPS  cash
STK_ID RPT_Date
600016 20111231  600016  4.3   NaN
601939 20111231  601939  2.5   NaN
7
U10-Forward

Einfach und leicht

df.dropna(subset=['EPS'],inplace=True)

quelle: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html

6
Nursnaaz

Diese Antwort ist viel einfacher als alle oben :)

df=df[df['EPS'].notnull()]
6
N T

Es kann an dieser Stelle hinzugefügt werden. '&' Kann verwendet werden, um zusätzliche Bedingungen hinzuzufügen, z.

df = df[(df.EPS > 2.0) & (df.EPS <4.0)]

Beachten Sie, dass pandas bei der Auswertung der Anweisungen Klammern benötigt.

1
David

Aus irgendeinem Grund hat keine der zuvor eingereichten Antworten für mich funktioniert. Diese grundlegende Lösung hat:

df = df[df.EPS >= 0]

Dabei werden natürlich auch Zeilen mit negativen Zahlen gelöscht. Also, wenn Sie diese möchten, ist es wahrscheinlich klug, dies auch nachher hinzuzufügen.

df = df[df.EPS <= 0]
0
samthebrand