Rijen met Panda’s DataFrame neerzetten waarvan de waarde in een bepaalde kolom NaN is

Ik heb dit DataFrameen wil alleen de records waarvan de EPS-kolom niet NaNis:

>>> 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.w.z. zoiets als df.drop(....)om dit resulterende dataframe te krijgen:

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

Hoe doe ik dat?


Antwoord 1, autoriteit 100%

Niet laten vallen, neem gewoon de rijen waar EPS niet NA is:

df = df[df['EPS'].notna()]

Antwoord 2, autoriteit 100%

Deze vraag is al opgelost, maar…

…overweeg ook de door Wouter voorgestelde oplossing in zijn originele opmerking. De mogelijkheid om ontbrekende gegevens te verwerken, waaronder dropna(), is expliciet ingebouwd in panda’s. Afgezien van potentieel verbeterde prestaties ten opzichte van handmatig doen, worden deze functies ook geleverd met een verscheidenheid aan opties die nuttig kunnen zijn.

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

Er zijn ook andere opties (zie documenten op http ://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html), inclusief het laten vallen van kolommen in plaats van rijen.

Heel handig!


Antwoord 3, autoriteit 13%

Ik weet dat dit al is beantwoord, maar alleen omwille van een puur panda’s-oplossing voor deze specifieke vraag in tegenstelling tot de algemene beschrijving van Aman (wat geweldig was) en voor het geval iemand anders dit tegenkomt:

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

Antwoord 4, autoriteit 8%

U kunt dit gebruiken:

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

Antwoord 5, autoriteit 4%

De eenvoudigste van alle oplossingen:

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

De bovenstaande oplossing is veel beter dan het gebruik van np.isfinite()


Antwoord 6, autoriteit 3%

Rijen met Panda’s DataFrame neerzetten waarvan de waarde in een bepaalde kolom NaN is

Dit is een oude vraag die doodgeslagen is, maar ik geloof dat er nog meer nuttige informatie naar boven komt in deze thread. Lees verder als u op zoek bent naar het antwoord op een van de volgende vragen:

  • Kan ik rijen laten vallen als een van de waarden nans heeft? Hoe zit het met als ze allemaal nan zijn?
  • Kan ik alleen naar nans kijken in specifieke kolommen bij het neerlaten van rijen?
  • Kan ik rijen laten vallen met een specifieke telling van NAN-waarden?
  • Hoe laat ik kolommen vallen in plaats van rijen?
  • Ik heb alle opties hierboven geprobeerd, maar mijn dataframe zal gewoon niet updaten!

DataFrame.dropna: gebruik en voorbeelden

Er is al gezegd dat df.dropnade canonieke methode is om nans uit dataframes te laten vallen, maar er is niets boven een paar visuele aanwijzingen om onderweg te helpen.

# Setup
df = pd.DataFrame({
    'A': [np.nan, 2, 3, 4],  
    'B': [np.nan, np.nan, 2, 3], 
    'C': [np.nan]*3 + [3]}) 
df                      
     A    B    C
0  NaN  NaN  NaN
1  2.0  NaN  NaN
2  3.0  2.0  NaN
3  4.0  3.0  3.0

Hieronder is een detail van de belangrijkste argumenten en hoe ze werken, gerangschikt in een FAQ-indeling.


Kan ik rijen laten vallen als een van de waarden nans heeft? Hoe zit het met als ze allemaal nan zijn?

Dit is waar de how=...argument komt van pas. Het kan een van

zijn

  • 'any'(standaard) – DROPS rijen Als ten minste één kolom NAN
  • heeft

  • 'all'– DROPS RIJEN ALLEEN ALS ALLE KOLOMMEN NATEN NANS
  • ZIJN

& lt;! _- & gt;

# Removes all but the last row since there are no NaNs 
df.dropna()
     A    B    C
3  4.0  3.0  3.0
# Removes the first row only
df.dropna(how='all')
     A    B    C
1  2.0  NaN  NaN
2  3.0  2.0  NaN
3  4.0  3.0  3.0

Opmerking
Als u alleen wilt zien welke rijen null zijn (IOW, als u een
booleaans masker van rijen), gebruik
isna:

df.isna()
       A      B      C
0   True   True   True
1  False   True   True
2  False  False   True
3  False  False  False
df.isna().any(axis=1)
0     True
1     True
2     True
3    False
dtype: bool

Om de inversie van dit resultaat te krijgen, gebruik
notna
in plaats daarvan.


Kan ik alleen naar NaN’s in specifieke kolommen kijken als ik rijen laat vallen?

Dit is een use case voor het argument subset=[...].

Geef een lijst met kolommen (of indexen met axis=1) op om panda’s te vertellen dat u alleen naar deze kolommen (of rijen met axis=1) wilt kijken wanneer het laten vallen van rijen (of kolommen met axis=1.

# Drop all rows with NaNs in A
df.dropna(subset=['A'])
     A    B    C
1  2.0  NaN  NaN
2  3.0  2.0  NaN
3  4.0  3.0  3.0
# Drop all rows with NaNs in A OR B
df.dropna(subset=['A', 'B'])
     A    B    C
2  3.0  2.0  NaN
3  4.0  3.0  3.0

Kan ik rijen met een specifiek aantal NaN-waarden laten vallen?

Dit is een use case voor het argument thresh=.... Specificeer het minimum aantal NON-NULL-waarden als een geheel getal.

df.dropna(thresh=1)  
     A    B    C
1  2.0  NaN  NaN
2  3.0  2.0  NaN
3  4.0  3.0  3.0
df.dropna(thresh=2)
     A    B    C
2  3.0  2.0  NaN
3  4.0  3.0  3.0
df.dropna(thresh=3)
     A    B    C
3  4.0  3.0  3.0

Het ding om hier op te merken is dat je moet specificeren hoeveel NON-NULL-waarden je wilt behouden, in plaats van hoeveel NULL-waarden je wilt laten vallen. Dit is een pijnpunt voor nieuwe gebruikers.

Gelukkig is de oplossing eenvoudig: als je een telling van NULL-waarden hebt, trek je deze gewoon af van de kolomgrootte om het juiste thresh-argument voor de functie te krijgen.

required_min_null_values_to_drop = 2 # drop rows with at least 2 NaN
df.dropna(thresh=df.shape[1] - required_min_null_values_to_drop + 1)
     A    B    C
2  3.0  2.0  NaN
3  4.0  3.0  3.0

Hoe verwijder ik kolommen in plaats van rijen?

Gebruik het argument axis=..., dit kan axis=0of axis=1zijn.

Laat de functie weten of u rijen (axis=0) of kolommen (axis=1) wilt neerzetten.

df.dropna()
     A    B    C
3  4.0  3.0  3.0
# All columns have rows, so the result is empty.
df.dropna(axis=1)
Empty DataFrame
Columns: []
Index: [0, 1, 2, 3]
# Here's a different example requiring the column to have all NaN rows
# to be dropped. In this case no columns satisfy the condition.
df.dropna(axis=1, how='all')
     A    B    C
0  NaN  NaN  NaN
1  2.0  NaN  NaN
2  3.0  2.0  NaN
3  4.0  3.0  3.0
# Here's a different example requiring a column to have at least 2 NON-NULL
# values. Column C has less than 2 NON-NULL values, so it should be dropped.
df.dropna(axis=1, thresh=2)
     A    B
0  NaN  NaN
1  2.0  NaN
2  3.0  2.0
3  4.0  3.0

Ik heb alle bovenstaande opties geprobeerd, maar mijn DataFrame wil gewoon niet updaten!

dropnaretourneert, net als de meeste andere functies in de pandas-API, een nieuw DataFrame (een kopie van het origineel met wijzigingen) als resultaat, dus u moet het terug toewijzen als u wijzigingen wilt zien.

df.dropna(...) # wrong
df.dropna(..., inplace=True) # right, but not recommended
df = df.dropna(...) # right

Referentie

https://pandas.pydata. org/pandas-docs/stable/reference/api/pandas.DataFrame.dropna.html

DataFrame.dropna(
    self, axis=0, how='any', thresh=None, subset=None, inplace=False)


Antwoord 7, autoriteit 2%

U kunt de dataframe-methode notnullgebruiken of omgekeerd van isnull, of numpy.isnan:

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

Antwoord 8, Autoriteit 2%

eenvoudige en eenvoudige manier

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

Bron: https: //pandas.pydata. Org / Panda’s-Docs / Stable / Gegenereerd / Panda’s.Dataframe.Dropna.html


Antwoord 9

Nog een andere oplossing die het feit gebruikt dat 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

Antwoord 10

Nog een versie:

df[~df['EPS'].isna()]

Antwoord 11

Het kan bij die ‘& amp;’ worden toegevoegd kan worden gebruikt om extra voorwaarden toe te voegen, b.g

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

Merk op dat bij het evalueren van de verklaringen Panda’s haakjes nodig heeft.


Antwoord 12

In datasets met een groot aantal kolommen is het nog beter om te zien hoeveel kolommen nulwaarden bevatten en hoeveel niet.

print("No. of columns containing null values")
print(len(df.columns[df.isna().any()]))
print("No. of columns not containing null values")
print(len(df.columns[df.notna().all()]))
print("Total no. of columns in the dataframe")
print(len(df.columns))

In mijn dataframe bevatte het bijvoorbeeld 82 kolommen, waarvan 19 ten minste één null-waarde.

Verder kunt u ook automatisch kolommen en rijen verwijderen, afhankelijk van welke meer null-waarden heeft
Hier is de code die dit intelligent doet:

df = df.drop(df.columns[df.isna().sum()>len(df.columns)],axis = 1)
df = df.dropna(axis = 0).reset_index(drop=True)

Opmerking:bovenstaande code verwijdert al uw null-waarden. Als je null-waarden wilt, verwerk ze dan eerst.

Other episodes