【问题标题】:Pandas: Drop leading rows with NaN threshold in dataframePandas:在数据框中删除具有 NaN 阈值的前导行
【发布时间】:2015-08-26 19:33:37
【问题描述】:

我有一个带有间歇性 NaN 值的 Pandas 数据框:

Index       Col1     Col2      Col3    Col4  Col5  Col6  Col7  Col8 
1991-12-31  100.000  100.000    NaN     NaN   NaN   NaN   NaN   NaN                     
1992-01-31   98.300  101.530    NaN     NaN   NaN   NaN   NaN   NaN                     
1992-02-29   97.602  100.230   98.713   NaN   NaN   NaN   NaN   NaN                     
1992-03-31   93.473    NaN    102.060   NaN   NaN   NaN   NaN   NaN                     
1992-04-30   94.529  102.205  107.755   NaN   NaN   NaN   NaN   NaN

我想删除具有 6 个或更多 NaN 的前导行。具体来说,在这种情况下,我只想删除索引为“1991-12-31”和“1992-01-31”的行。

使用 df.dropna(thresh = 6) 不起作用,因为它也会删除行 '1992-03-31'。

一种解决方案是计算每一行中的 NaN,当 NaN 的数量小于 6 时,在第一行停止。

任何更快/更清洁的解决方案?

编辑:为清楚起见和@Alexander 的评论进行了编辑

【问题讨论】:

  • “1992-02-29”有 5 个 NaN - 它有什么不同可以让您确定不想放弃它?
  • @chrisb,删除前导行。
  • 所有行至少有五个 NaN。当然,您的意思是超过 5 个 NaN 的行。
  • @Alexander 感谢您指出这一点。修正了问题。

标签: python numpy pandas dataframe


【解决方案1】:

你只需要df[(df.irow(0).isnull().sum()>5):]

当第一行有超过 5 个nan 时,df.irow(0).isnull().sum()>5True 并且df[(df.irow(0).isnull().sum()>5):] 只是df[1:]:第一行被省略。

为了解决@DSM 的观点,我们可以考虑:

df.ix[np.argwhere(df.isnull().sum(1)<=5).ravel()[0]:]

基本上这是从第一行(不是在原始 df 中,而是在小于或等于 5 nan 的第一行)开始对 DataFrame 进行切片。这样,如果第 1 行有 6 个,第 2 行有 7 个,第 3 行有 8 个nans,则结果数据帧将从第 4 行开始。如果第一行只有 1 个nan,则结果为df[0:],不会跳过任何行。

【讨论】:

  • 我怀疑如果第二行有 8 个 NaN,那也算作要删除的前导行。
  • 美丽。这回答了这个问题。我不知道 ravel 和 argwhere 的功能。谢谢@CTZhu
【解决方案2】:

假设名为Index 的列实际上是索引,您可以统计每行中空值的数量,并选择那些大于您的阈值的。如果有任何返回,则删除第一个(即前行)。

idx = df[df.isnull().sum(axis=1) <= 5].index
if len(idx) > 0:
    df = df.ix[idx[0]:]

>>> df
              Col1     Col2     Col3  Col4  Col5  Col6  Col7  Col8
Index                                                             
1992-02-29  97.602  100.230   98.713   NaN   NaN   NaN   NaN   NaN
1992-03-31  93.473      NaN  102.060   NaN   NaN   NaN   NaN   NaN
1992-04-30  94.529  102.205  107.755   NaN   NaN   NaN   NaN   NaN

【讨论】:

  • 我需要删除所有 > 5 NaN 的前导行,而不仅仅是第一个。
  • 我相信“前导行”这个词有点误导。也许只是具有 6 个或更多 NaN 的“所有行”?如果是这样,上面的编辑应该可以工作,我只是在drop 语句中将 idx[0] 更改为 idx。
  • 没有。我特别指的是“领先行”。对于“所有行”,我可以简单地使用 df.dropna(thresh = 5)。但是,这不是我的问题所需的输出。
  • 您能否阐明您对“前导行”的定义?
  • 满足条件的前 'n' 行。如果任何 1 行不满足条件,则该行之后的任何行也不满足条件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 2017-11-12
  • 2012-06-07
  • 2011-08-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多