【问题标题】:finding columns with recurring nan series between first and last real value在第一个和最后一个实际值之间查找具有重复 nan 系列的列
【发布时间】:2020-05-28 14:20:25
【问题描述】:

我目前正在清理一个相当大的时间序列文件。正如您在下面的数据框中看到的那样,大多数列以一些 NaN 开头和结尾。

import pandas as pd
import numpy as np

df = pd.DataFrame({
               'a': [np.NaN, np.NaN, 3, 4, 5, 3, 2, 1, 2, 1, np.NaN, np.NaN],
               'b': [np.NaN, 80, 84, 30, 3, np.NaN, np.NaN, np.NaN, 4, 3, 2, 1],
               'c': [np.NaN, np.NaN, np.NaN, np.NaN, np.NaN, 80, 84, 1, 2, 3, 4 , 5],
               'd': [np.NaN, 40, 8, 2, 3, 4, 5, 6, 7, 8, 7, np.NaN],
               'e': [np.NaN, 1, 2, 3, np.NaN, np.NaN, 6, 7, 8, 9, 1 ,2]})

这对我来说不是问题,但是:如果在 NaN 的第一个实值和列的最后一个值之后有一系列 2,我需要检测它们。所以我想做的和插值法背后的想法/思考非常相似:

df = df.interpolate(method = 'linear', limit_area='inside', limit = 2)       

但相反,我想获取包含这些重复出现的 NaN 系列的列。因此,查看上面的示例数据框,我希望列“b”和“e”作为输出,因为这些列是唯一在第一个和最后一个真实的非 NaN 值之间具有两个以上重复 NaN 的列。所以我不是在寻找一种插值方法,而是一种检测这些列的方法

有没有人建议如何做到这一点?提前致谢

【问题讨论】:

    标签: python dataframe


    【解决方案1】:

    这可以使用派生自consecutive count problem的方法解决

    在这里,我将定义一个函数来计算一个系列中连续 NaN 的最大数量:

    def seqnan(x):
        y = x[~x.isna()]
        y = x[y.index[0]:y.index[-1]]      # limit from first non NaN value to last one
        # the magic formula (see ref. post for details)
        t = y[y.isna()].groupby((y.isna()&(~y.shift().isna())).cumsum()).cumcount().max()
        return 0 if np.isnan(t) else t+1
    

    现在我们有了:

    >>> df.apply(seqnan)
    a    0
    b    3
    c    0
    d    0
    e    2
    dtype: int64
    

    所以要让列名在第一个非 NaN 到最后一个非 NaN 中至少有 2 个连续的 NaN 值,您可以这样做

    tmp = df.apply(seqnan)
    cols = tmp[tmp >= 2].index.tolist()
    

    达到预期

    ['b', 'e']
    

    【讨论】:

    • 非常感谢,这正是我想要的!
    猜你喜欢
    • 2019-12-09
    • 2018-03-18
    • 2017-12-18
    • 2022-12-18
    • 2016-11-25
    • 2019-08-12
    • 1970-01-01
    • 1970-01-01
    • 2017-08-25
    相关资源
    最近更新 更多