1163

我有这个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

我怎么做?

4

14 回答 14

1224

不要放弃,只取 EPS 不是 NA 的行:

df = df[df['EPS'].notna()]
于 2012-11-16T09:34:38.297 回答
1109

这个问题已经解决了,但是...

...还要考虑 Wouter 在其原始评论中建议的解决方案。处理缺失数据的能力,包括dropna(),明确地内置在 pandas 中。除了与手动操作相比可能会提高性能外,这些功能还带有各种可能有用的选项。

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上的文档),包括删除列而不是行。

很方便!

于 2012-11-17T20:27:33.253 回答
139

我知道这已经得到了回答,但只是为了这个特定问题的纯粹熊猫解决方案,而不是 Aman 的一般描述(这很棒),以防其他人发生这种情况:

import pandas as pd
df = df[pd.notnull(df['EPS'])]
于 2014-04-23T05:37:45.533 回答
106

你可以使用这个:

df.dropna(subset=['EPS'], how='all', inplace=True)
于 2017-08-02T16:28:41.573 回答
41

最简单的解决方案:

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

上述解决方案比使用 np.isfinite() 好得多

于 2017-11-23T12:08:11.147 回答
41

如何删除某一列中值为 NaN 的 Pandas DataFrame 行

这是一个老问题,已经被打死了,但我相信在这个线程上有一些更有用的信息可以浮出水面。如果您正在寻找以下任何问题的答案,请继续阅读:

  • 如果行的任何值具有 NaN,我可以删除行吗?如果它们都是 NaN 怎么办?
  • 删除行时,我只能查看特定列中的 NaN 吗?
  • 我可以删除具有特定 NaN 值计数的行吗?
  • 如何删除列而不是行?
  • 我尝试了上述所有选项,但我的 DataFrame 不会更新!

DataFrame.dropna: 用法和例子

已经有人说这df.dropna是从 DataFrames 中删除 NaN 的规范方法,但是在此过程中没有什么比一些视觉提示更能提供帮助的了。

# 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

以下是最重要的论点及其工作原理的详细信息,以常见问题解答格式排列。


如果行的任何值具有 NaN,我可以删除行吗?如果它们都是 NaN 怎么办?

这就是how=...论证派上用场的地方。它可以是其中之一

  • 'any'(默认) - 如果至少一列有 NaN,则删除行
  • 'all'- 仅当所有列都有 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

注意
如果您只想查看哪些行为空(IOW,如果您想要行的布尔掩码),请使用 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

要获得此结果的反转,请 notna 改用。


删除行时,我只能查看特定列中的 NaN 吗?

这是subset=[...]参数的一个用例。

指定一个列列表(或带有 的索引axis=1)告诉 pandasaxis=1在删除行(或带有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

我可以删除具有特定 NaN 值计数的行吗?

这是thresh=...参数的一个用例。将 NON-NULL 值的最小数量指定为整数。

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

这里要注意的是,您需要指定要保留多少个 NON-NULL 值,而不是要删除多少个 NULL 值。这是新用户的痛点。

幸运的是,修复很简单:如果您有 NULL 值的计数,只需从列大小中减去它即可获得函数的正确 thresh 参数。

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

如何删除列而不是行?

使用axis=...参数,它可以是axis=0or axis=1

告诉函数您是要删除行 ( axis=0) 还是删除列 ( 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

我尝试了上述所有选项,但我的 DataFrame 不会更新!

dropna, 与 pandas API 中的大多数其他函数一样,返回一个新的 DataFrame(带有更改的原始副本)作为结果,因此如果您想查看更改,应该将其分配回去。

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

参考

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)

在此处输入图像描述

于 2020-06-18T07:42:24.143 回答
27

简单易行的方法

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

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

于 2019-01-22T08:26:39.203 回答
26

您可以使用数据框方法notnullisnullnumpy.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
于 2015-12-04T07:01:56.243 回答
14

另一个使用以下事实的解决方案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
于 2017-04-20T21:15:56.967 回答
5

另一个版本:

df[~df['EPS'].isna()]
于 2020-02-08T07:59:30.153 回答
2

可以添加'&'可以用于添加附加条件,例如

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

请注意,在评估语句时,pandas 需要括号。

于 2016-03-15T15:33:31.850 回答
2

在具有大量列的数据集中,最好查看有多少列包含空值以及有多少列不包含。

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)

注意:上面的代码删除了所有空值。如果您想要空值,请先处理它们。

于 2019-12-14T04:23:27.593 回答
0

以下方法对我有用。如果上述方法都不起作用,那将有所帮助:

df[df['colum_name'].str.len() >= 1]

基本思想是仅当长度强度大于 1 时才拾取记录。这在处理字符串数据时特别有用

最好的!

于 2021-12-08T06:17:35.513 回答
-1

您可以尝试:

df['EPS'].dropna()
于 2022-02-21T19:55:01.587 回答