【问题标题】:Select rows that lie within datetime intervals选择日期时间间隔内的行
【发布时间】:2019-05-13 19:31:48
【问题描述】:

我正在尝试比较两个数据帧并从第一个数据帧中删除不在第二个数据帧中的日期之间的行(或...选择那些 在第二个数据帧中的日期之间)。选择应该是包容性的。这可能真的很简单,但它现在不适合我。

示例数据如下。对于数据框 1,可以使用从 2018 年 7 月 1 日到 2018 年 11 月 30 日结束的每日数据生成,并在“数字”列中使用随机数。数据帧 1 中的 ... 用于显示跳过的数据,但数据在真实数据帧中。

数据框 1:

               Number
Date
2018-07-01     15.2
2018-07-02     17.3
2018-07-03     19.5
2018-07-04     13.7
2018-07-05     19.1
...
2018-09-15     30.4
2018-09-16     25.7
2018-09-17     21.2
2018-09-18     19.7
2018-09-19     23.4
...
2018-11-01     30.8
2018-11-02     47.2
2018-11-03     25.3
2018-11-04     39.7
2018-11-05     43.8

数据框 2:

              Change
Date
2018-07-02     Start
2018-07-04     End
2018-09-16     Start
2018-09-18     End
2018-11-02     Start
2018-11-04     End

对于上面的例子,输出应该是:

               Number
Date
2018-07-02     17.3
2018-07-03     19.5
2018-07-04     13.7
2018-09-16     25.7
2018-09-17     21.2
2018-09-18     19.7
2018-11-02     47.2
2018-11-03     25.3
2018-11-04     39.7

【问题讨论】:

    标签: python pandas datetime dataframe


    【解决方案1】:

    你可以试试这个,我希望 Start 和 End 一个接一个地出现并排序。

    df3 = pd.concat([df[i:j] for i,j in zip(df2.loc[df2['Change']=='Start'].index, df2.loc[df2['Change']=='End'].index)]))
                 Number
    Date              
    2018-07-02    17.3
    2018-07-03    19.5
    2018-07-04    13.7
    2018-09-16    25.7
    2018-09-17    21.2
    2018-09-18    19.7
    2018-11-02    47.2
    2018-11-03    25.3
    2018-11-04    39.7
    

    【讨论】:

    • 这给了我我期望在更大的数据集上看到的答案,而且它非常pythonic。谢谢!
    【解决方案2】:

    您可以从df2 的索引构建IntervalIndex 并以对数时间进行搜索。

    df2.index = pd.to_datetime(df2.index)
    idx = pd.IntervalIndex.from_arrays(df2.index[df.Change == 'Start'], 
                                       df2.index[df.Change == 'End'],
                                       closed='both')
    
    df1[idx.get_indexer(pd.to_datetime(df1.index)) > -1]
    
                Number
    Date              
    2018-07-02    17.3
    2018-07-03    19.5
    2018-07-04    13.7
    2018-09-16    25.7
    2018-09-17    21.2
    2018-09-18    19.7
    2018-11-02    47.2
    2018-11-03    25.3
    2018-11-04    39.7
    

    【讨论】:

    • 我喜欢这个,但我没有得到答案,我希望得到更大的数据集。也许我做错了什么。你能解释一下df1[idx.get_indexer(pd.to_datetime(df1.index)) > -1]这行吗?
    • @EricD.Brown idx.get_indexer 接受日期列表,并返回每个日期的间隔索引(如果其中任何一个存在)。如果日期不在任何间隔中,则返回 -1。您可能还想尝试idx.get_indexer_non_unique。用法见this post
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-02
    • 2012-06-19
    • 2012-01-01
    • 1970-01-01
    相关资源
    最近更新 更多