【问题标题】:Find 'next' non-null value in column在列中查找“下一个”非空值
【发布时间】:2021-10-01 09:39:47
【问题描述】:

我正在尝试创建一个新列,该列使用以下 df 作为起点,将下一个非空值的行索引附加到当前非空值旁边:

ts = [
        datetime.strptime('2016-06-19 22:01:22.229', '%Y-%m-%d %H:%M:%S.%f'),
        datetime.strptime('2016-06-19 23:32:08.109', '%Y-%m-%d %H:%M:%S.%f'),
        datetime.strptime('2016-06-20 02:50:22.181', '%Y-%m-%d %H:%M:%S.%f'),
        datetime.strptime('2016-06-20 06:12:44.249', '%Y-%m-%d %H:%M:%S.%f'),
        datetime.strptime('2016-06-20 19:27:22.129', '%Y-%m-%d %H:%M:%S.%f'),
        datetime.strptime('2016-06-21 11:39:08.119', '%Y-%m-%d %H:%M:%S.%f'),
        datetime.strptime('2016-06-21 16:59:22.610', '%Y-%m-%d %H:%M:%S.%f')
        ]

score = [ np.nan, np.nan, 77.692, np.nan, 77.709, np.nan, 76.145 ]


df = pd.DataFrame(data={'date': ts, 'jack': score})

输出如下所示:

                     date    jack  nxt_nn_value
0 2016-06-19 22:01:22.229     NaN           NaN
1 2016-06-19 23:32:08.109     NaN           NaN
2 2016-06-20 02:50:22.181  77.692             4
3 2016-06-20 06:12:44.249     NaN           NaN
4 2016-06-20 19:27:22.129  77.709             6
5 2016-06-21 11:39:08.119     NaN           NaN
6 2016-06-21 16:59:22.610  76.145           NaN

我找到了一个涉及该问题的链接,但我无法适应.. How can I get the index of next non-NaN number with series in pandas?

提前感谢您提供的任何帮助。

【问题讨论】:

    标签: python pandas indexing


    【解决方案1】:

    我们可以在jack 中找到notnull 的值。然后shift 向上。然后使用loc 分配结果,并使用values 打破索引对齐:

    m = df['jack'].notnull()
    df.loc[m, 'nxt_nn_value'] = pd.Series(m[m].index).shift(-1).values
    

    df:

                         date    jack  nxt_nn_value
    0 2016-06-19 22:01:22.229     NaN           NaN
    1 2016-06-19 23:32:08.109     NaN           NaN
    2 2016-06-20 22:50:22.181  77.692           4.0
    3 2016-06-20 06:12:44.249     NaN           NaN
    4 2016-06-20 19:27:22.129  77.709           6.0
    5 2016-06-21 11:39:08.119     NaN           NaN
    6 2016-06-21 16:59:22.610  76.145           NaN
    

    解释:

    首先找到jack中的值在哪里notnull

    m = df['jack'].notnull()
    
    0    False
    1    False
    2     True
    3    False
    4     True
    5    False
    6     True
    Name: jack, dtype: bool
    

    过滤来获取索引有很多等效的方法可以做到这一点:

    m[m].index
    
    Int64Index([2, 4, 6], dtype='int64')
    

    然后转换为一个系列,以便它可以移动,这将给出“下一个”索引:

    pd.Series(m[m].index).shift(-1)
    
    0    4.0
    1    6.0
    2    NaN
    dtype: float64
    

    然后仅在值为notnull 的情况下分配回DataFrame,需要values 来破坏Series 和DataFrame 之间的索引对齐:

    df.loc[m, 'nxt_nn_value'] = pd.Series(m[m].index).shift(-1).values
    

    【讨论】:

    • 解释如金。谢谢我是新手,非常感谢这样简洁的叙述。谢谢
    • 对于每个超过 10000 行的数据框字典,这是最好的方法吗?
    • 我不知道如何量化“最佳”,因为我没有任何可比较的东西,但是,我发现在 20,000 行的数据帧上大约需要 100 毫秒才能完成。对于 10,000 行,它是 64.9624 ms。假设 DataFrame 在该范围内,这意味着每秒 10-18 个。
    • 干杯。在此之后,我想对 df 进行进一步调整,但我将在接下来的 5 分钟内作为新问题打开,以便可以关闭此问题
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-13
    • 2011-01-03
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 2021-12-03
    • 1970-01-01
    相关资源
    最近更新 更多