【问题标题】:Drop row with NaN value in a Dataframe, only after the first non NaN Value在数据框中删除具有 NaN 值的行,仅在第一个非 NaN 值之后
【发布时间】:2021-09-10 20:46:20
【问题描述】:

我有一个包含不同列的数据框。在实际值开始之前,某些列可能以一系列 NaN 值开始。但是,在每列的第一个非 NaN 值之后,也可以出现一些 NaN 值。例如:

              A    B    C
2021-08-31  1.0  NaN  5.0
2021-09-01  2.0  NaN  NaN
2021-09-02  4.0  3.0  NaN
2021-09-03  NaN  7.0  5.0
2021-09-06  2.0  5.0  5.0
2021-09-07  9.0  NaN  5.0
2021-09-08  4.0  5.0  NaN

我想删除所有存在 NaN 值的行但仅在列中的第一个非 NaN 值之后。换句话说,第一个非 NaN 值之前的 NaN 值在删除过程中不考虑在内。

所以前面的例子看起来像这样:

              A    B    C
2021-08-31  1.0  NaN  5.0
2021-09-06  2.0  5.0  5.0

我开始使用“first_valid_date”列表寻找解决方案,然后在列的 first_valid_date 加上值为 NaN 之后的索引条件下删除,但我在使用 2 个条件(NaN)删除值时遇到问题和索引):

df.drop(df[df.isna().any(axis=1) & df.index > mydateindex].index)

【问题讨论】:

    标签: python dataframe


    【解决方案1】:

    尝试将此与locisnanotnashift 一起使用:

    >>> df.loc[(~(df.shift().notna() & df.isna() & df.shift(-1).notna())).all(1)]
                  A    B
    2021-08-31  1.0  NaN
    2021-09-01  2.0  NaN
    2021-09-02  4.0  3.0
    2021-09-06  2.0  5.0
    2021-09-08  4.0  5.0
    >>> 
    

    【讨论】:

    • Thx,它几乎可以工作,只是它不会在所有列都有其 first_valide_date 之前删除行(我将更改我的示例以使其更清晰)
    • 感谢您的帮助,您在这个例子中是对的。我以为我明白了它不起作用的原因,所以我举了一个更简单的例子。显然我没有很好地理解;)。我会用一个我确定不行的帖子来修改。
    • @FredDujardin 好吧,我几乎 100% 确定这适用于所有事情......如果有帮助,请记住选择这个答案:)
    • 用你的代码,结果保持行:'2021-09-01'、'2021-09-02'和'2021-09-08',在第一个之后的C列上都带有NaN验证日期
    • 看起来在第一个有效日期之后有连续 NaN 的 pb 和最后一行是 NaN
    【解决方案2】:

    我想我找到了正确的方法:

    df.loc[~(df.fillna(method='ffill').notna() & ~df.notna()).max(axis=1)]
    

    【讨论】:

      最近更新 更多