Jak upuścić wiersze ramki danych Pandy, których wartością w określonej kolumnie jest NaN
Mam to DataFrame
i chcę tylko te rekordy, których EPS
kolumna nie jest NaN
:
>>> 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
...tj. coś w rodzaju df.drop(....)
, aby uzyskać ten wynikowy dataframe:
STK_ID EPS cash
STK_ID RPT_Date
600016 20111231 600016 4.3 NaN
601939 20111231 601939 2.5 NaN
Jak mam to zrobić? 12 answers
Nie upuszczaj, po prostu weź wiersze, w których EPS nie jest NA:
df = df[df['EPS'].notna()]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-16 07:46:41
To pytanie jest już rozwiązane, ale...
...rozważ również rozwiązanie zaproponowane przez Woutera w jego oryginalnym komentarzu . Możliwość obsługi brakujących danych, w tym dropna()
, jest wbudowana w pandy jawnie. Oprócz potencjalnie zwiększonej wydajności wykonywania tego ręcznie, funkcje te są również wyposażone w wiele opcji, które mogą być przydatne.
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
Istnieją również inne opcje (patrz dokumenty na http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html ), w tym zrzucanie kolumn zamiast wierszy.
Bardzo poręczne!Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-14 00:04:56
Wiem, że już na to odpowiedziano, ale tylko ze względu na czysto pandowe rozwiązanie tego konkretnego pytania, w przeciwieństwie do ogólnego opisu z Aman (co było wspaniałe) i na wypadek, gdyby ktoś inny się na to zdarzył: {]}
import pandas as pd
df = df[pd.notnull(df['EPS'])]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-23 05:37:45
Możesz użyć tego:
df.dropna(subset=['EPS'], how='all', inplace=True)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-22 08:04:53
Najprostsze ze wszystkich rozwiązań:
filtered_df = df[df['EPS'].notnull()]
Powyższe rozwiązanie jest o wiele lepsze niż użycie np.isfinite ()
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-08 15:17:20
Możesz użyć metody dataframe notnull lub odwrotności isnull , lub 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-04 07:01:56
Prosty i łatwy sposób
df.dropna(subset=['EPS'],inplace=True)
Źródło: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-01-23 10:13:13
Jak upuścić wiersze ramki danych pand, których wartością w określonej kolumnie jest NaN
To stare pytanie, które zostało pobite na śmierć, ale wierzę, że jest więcej przydatnych informacji, które można znaleźć w tym wątku. Czytaj dalej, Jeśli szukasz odpowiedzi na jedno z następujących pytań:
- Czy Mogę upuścić wiersze, jeśli którakolwiek z jego wartości ma Nan? A jeśli wszyscy to NaN?
- Czy mogę patrzeć tylko na Nan w określonych kolumnach podczas upuszczania wiersze?
- Czy Mogę upuścić wiersze z określoną liczbą wartości NaN?
- jak zrzucić kolumny zamiast wierszy?
- wypróbowałem wszystkie powyższe opcje, ale moja ramka danych po prostu nie chce się zaktualizować!
DataFrame.dropna
: użycie i przykłady
Mówi się już, że df.dropna
jest kanoniczną metodą usuwania Nan z ramek danych, ale nie ma to jak kilka wizualnych wskazówek, które pomogą po drodze.
# 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
Poniżej szczegóły najważniejszych argumenty i sposób ich działania, ułożone w formacie FAQ.
Czy Mogę upuścić wiersze, jeśli którakolwiek z jego wartości ma Nan? A jeśli wszyscy to NaN?
Tutaj przydaje się argument how=...
. Może to być jeden z
-
'any'
(domyślnie) - usuwa wiersze, jeśli co najmniej jedna kolumna ma NaN -
'all'
- usuwa wiersze tylko wtedy, gdy wszystkie jego kolumny mają Nan
# 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
Uwaga
Jeśli chcesz tylko zobaczyć, które wiersze are null( IOW, if you want a boolean mask of rows), użyjisna
: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
Aby uzyskać inwersję tego wyniku, użyj
notna
zamiast tego.
Czy mogę patrzeć tylko na Nan w określonych kolumnach podczas upuszczania wierszy?
Jest to przypadek użycia argumentu subset=[...]
.
Określ listę kolumn (lub indeksów z axis=1
), aby powiedzieć, że chcesz patrzeć tylko na te kolumny (lub wiersze z axis=1
) podczas upuszczania wierszy (lub kolumn z 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
Czy Mogę upuścić wiersze z określoną liczbą wartości NaN?
Jest to przypadek użycia argumentu thresh=...
. Określ minimalną liczbę wartości innych niż NULL jako liczbę całkowitą.
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
Należy tutaj zwrócić uwagę na to, ile wartości innych niż NULL chcesz zachować, a nie ile wartości NULL chcesz upuścić. To problem dla nowych użytkowników.
Na szczęście poprawka jest łatwa: jeśli masz liczbę wartości NULL, po prostu odejmij go od rozmiaru kolumny, aby uzyskać prawidłowy argument progu dla funkcji.
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
Jak zrzucić kolumny zamiast wierszy?
Użyj argumentu axis=...
, Może to być axis=0
lub axis=1
.
Mówi funkcji, czy chcesz upuścić wiersze (axis=0
) czy upuścić kolumny (axis=1
).
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
Próbowałem wszystkich opcji powyżej, ale moja ramka danych po prostu nie chce się zaktualizować!
dropna
, podobnie jak większość innych funkcji w pandas API zwraca nową DataFrame (kopia oryginału ze zmianami) jako wynik, więc należy przypisać go z powrotem, jeśli chcesz zobaczyć zmiany.
df.dropna(...) # wrong
df.dropna(..., inplace=True) # right, but not recommended
df = df.dropna(...) # right
Odniesienie
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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-03 22:07:23
Jeszcze jedno rozwiązanie, które wykorzystuje fakt, że 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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-20 21:15:56
Inna wersja:
df[~df['EPS'].isna()]
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-10 09:19:10
Można dodać, że ' & ' może być użyte do dodania dodatkowych warunków np.
df = df[(df.EPS > 2.0) & (df.EPS <4.0)]
Zauważ, że przy ocenie wypowiedzi pandy potrzebują nawiasu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-26 23:12:08
W zestawach danych o dużej liczbie kolumn jeszcze lepiej jest sprawdzić, ile kolumn zawiera wartości null, a ile nie.
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))
Na przykład w moim dataframe zawierała ona 82 kolumny, z czego 19 zawierało co najmniej jedną wartość null.
Ponadto możesz również automatycznie usunąć cols i rows w zależności od tego, który ma więcej wartości null
Oto kod, który robi to inteligentnie:
df = df.drop(df.columns[df.isna().sum()>len(df.columns)],axis = 1)
df = df.dropna(axis = 0).reset_index(drop=True)
Uwaga: powyższy kod usuwa wszystkie Twoje null wartości. Jeśli chcesz wartości null, przetworz je wcześniej.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-02-17 11:00:16