У меня есть DataFrame и я хочу только записи, столбец EPS которых не равен 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

... т.е . что-то вроде df.drop(....), чтобы получить этот результирующий кадр данных:

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

Как я могу это сделать?

905
bigbug 16 Ноя 2012 в 13:17

13 ответов

Лучший ответ

Не бросайте, просто возьмите строки, где EPS не NA:

df = df[df['EPS'].notna()]
557
AMC 16 Фев 2020 в 07:46

Еще одно решение, которое использует тот факт, что 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 20 Апр 2017 в 21:15

Вы можете использовать метод dataframe notnull или наоборот isnull или 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
21
Anton Protopopov 4 Дек 2015 в 07:01

Он может быть добавлен при том, что «&» может использоваться для добавления дополнительных условий, например,

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

Обратите внимание на то, что при оценке утверждений пандам нужна скобка.

0
aesede 26 Янв 2017 в 23:12

Другая версия:

df[~df['EPS'].isna()]
1
Georgy 10 Фев 2020 в 09:19

Одним из решений может быть

df = df[df.isnull().sum(axis=1) <= Cutoff Value]

Другой способ может быть

df= df.dropna(thresh=(df.shape[1] - Cutoff_value))

Надеюсь, это будет полезно.

-1
Amit Gupta 23 Сен 2019 в 11:00

Простой и легкий способ

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

Источник: https://pandas.pydata.org/pandas -docs / стабильный / генерироваться / pandas.DataFrame.dropna.html

16
Nursnaaz 23 Янв 2019 в 10:13

По какой-то причине ни один из ранее представленных ответов не работал для меня. Это основное решение сделало:

df = df[df.EPS >= 0]

Хотя, конечно, это приведет и к появлению строк с отрицательными числами. Так что, если вы хотите их, возможно, стоит добавить это и после.

df = df[df.EPS <= 0]
-1
samthebrand 9 Окт 2015 в 18:25

Этот вопрос уже решен, но ...

... также рассмотрим решение, предложенное Wouter в его оригинальный комментарий. Способность обрабатывать недостающие данные, включая dropna(), встроена в панды явно. Помимо потенциально улучшенной производительности по сравнению с выполнением вручную, эти функции также имеют множество опций, которые могут быть полезны.

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

Есть и другие варианты (см. Документы на http: // pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.dropna.html), включая удаление столбцов вместо строк.

Довольно удобно!

869
ayhan 14 Авг 2017 в 00:04

Самое простое из всех решений:

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

Приведенное выше решение лучше, чем использование np.isfinite ().

34
ayhan 8 Авг 2018 в 15:17

Я знаю, что на это уже был дан ответ, но только ради решения панд на этот конкретный вопрос, в отличие от общего описания от Амана (что было замечательно), и в случае, если кто-то еще случится с этим:

import pandas as pd
df = df[pd.notnull(df['EPS'])]
120
Kirk Hadley 23 Апр 2014 в 05:37

В наборах данных, имеющих большое количество столбцов, еще лучше увидеть, сколько столбцов содержат нулевые значения, а сколько нет.

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))

Например, в моем фрейме данных он содержал 82 столбца, из которых 19 содержали хотя бы одно нулевое значение.

Кроме того, вы также можете автоматически удалять столбцы и строки , в зависимости от того, какие значения больше нуля.
Вот код, который делает это разумно:

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

Примечание. Код выше удаляет все ваши нулевые значения. Если вы хотите нулевые значения, обработайте их раньше.

1
Pradeep Singh 17 Фев 2020 в 11:00

Вы можете использовать это:

df.dropna(subset=['EPS'], how='all', inplace=True)
53
Georgy 22 Окт 2019 в 08:04