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

我有一个DataFrame

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

然后我只想要EPS不是NaN的logging,也就是df.drop(....)将返回dataframe如下:

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

我怎么做?

不要drop 。 只需要EPS有限的行:

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

这个问题已经解决了,但…

也考虑Wouter在他原来的评论中提出的解决scheme。 能够处理丢失的数据,包括dropna() ,明确地build立在pandasdropna() 。 除了手动进行性能改进之外,这些function还带有各种可能有用的选项。

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

非常方便!

我知道这已经被回答了,但是为了纯粹的pandas解决这个具体的问题,而不是从阿曼的一般描述(这真是太棒了),以及其他人发生这种情况:

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

您可以使用isnull或numpy.isnan的 notnull或inverse的数据框方法:

 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 

你可以使用这个:

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

另一种解决scheme是使用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 

它可能被添加在'&'可以用来添加额外的条件,例如

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

请注意,在评估报表时,大pandas需要括号。

由于某种原因,以前提交的答案没有为我工作。 这个基本的解决办法是

 df = df[df.EPS >= 0] 

当然,这也会使负数的行数下降。 所以如果你想要的话,也可以添加这个。

 df = df[df.EPS <= 0]