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

我怎么做呢?


当前回答

不要掉,只取EPS不是NA的行:

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

其他回答

不要掉,只取EPS不是NA的行:

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

你可以试试:

df['EPS'].dropna()

你也可以使用notna内部查询:

In [4]: df.query('EPS.notna().values')
Out[4]: 
                 STK_ID.1  EPS  cash
STK_ID RPT_Date                     
600016 20111231    600016  4.3   NaN
601939 20111231    601939  2.5   NaN

如何删除熊猫数据帧的行,其值在某一列是NaN

这是一个老问题,但我相信在这个帖子中会有一些更有用的信息浮出水面。如果你正在寻找以下问题的答案,请继续阅读:

如果它的值有nan,我可以删除行吗?如果它们都是NaN呢? 当删除行时,我可以只查看特定列中的nan吗? 我可以删除具有特定NaN值计数的行吗? 如何删除列而不是行? 我尝试了上面所有的选项,但我的DataFrame就是不会更新!


DataFrame。dropna:用法和例子

我们已经说过,df。dropna是从dataframe中删除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,如果你想要一个 行布尔掩码),使用 并网发电: df.isna () A b c 0真真假假 1假真假真 2假假真 3假假假 df.isna () .any(轴= 1) 0真实 1真正的 2真 3错误 dtype: bool 要获得此结果的反转,请使用 notna 代替。


当删除行时,我可以只查看特定列中的nan吗?

这是子集=[…]]参数。

指定一个列(或轴=1的索引)列表,以告诉pandas在删除行(或轴=1的列)时只希望查看这些列(或轴=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=0或axis=1。

告诉函数是要删除行(轴=0)还是删除列(轴=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,子集=None, inplace=False)

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

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

非常方便!