【问题标题】:How to get frequent Timestamps between an early and a late daytime?如何在早晚之间获得频繁的时间戳?
【发布时间】:2020-11-18 13:36:00
【问题描述】:

我有一个带有数百万个时间戳索引的 df,它保持频繁的标记 (例如,每 5 分钟一次)

但有洞

(= 一些理想顺序的时间戳丢失,甚至可能在整个数据帧中,

例如,“20:05:00”可能永远不会出现,尽管它的邻居“20:00:00”和“20:10:00”可能存在。)。

.

我需要解决那些“漏洞”。但仅限于特定的早间和特定的晚间。

Time                 Vals
2019-06-17 08:45:00   NaN 
2019-06-17 08:50:00   NaN 
2019-06-17 08:55:00   NaN 
2019-06-17 09:00:00   NaN 
2019-06-17 09:05:00   NaN 
2019-06-17 09:10:00   NaN 
2019-06-17 09:15:00   NaN 
2019-06-17 09:20:00   NaN 
2019-06-17 09:25:00   NaN 
2019-06-17 09:30:00   NaN 
2019-06-17 09:35:00   NaN 
2019-06-17 09:40:00   NaN 
2019-06-17 09:45:00   NaN 
2019-06-17 09:50:00   NaN 
2019-06-17 09:55:00   NaN 
2019-06-17 10:00:00   NaN 
2019-06-17 10:05:00   NaN 
2019-06-17 10:10:00   NaN 
2019-06-17 10:15:00   NaN 
2019-06-17 10:20:00   NaN 
                ...   ...
                ...   ...
                ...   ...
Name: Vals, dtype: float64

可以通过以下方式获取白天的早点和晚点:

df.index = pd.MultiIndex.from_tuples(zip(X.index.date,X.index.time))

# get unique times 
dates = X.index.get_level_values(0).unique()
times = X.index.get_level_values(1).unique()

early_daytime = times.min
late_daytime  = times.max

# back to original index format: reduce MultiIndex to 1D datetime index, sort
X.index = [datetime.combine(date,time) for date,time in X.index.values]
X = X.sort_index()

假设伪频率为 5 分钟。

我怎样才能获得每个“以 5 分钟为单位”的缺失时间戳包含在“日期”“early_daytime”和“late_daytime”之间的每一天强>?

注意:变量 "times"index 不能不包含应包含在5分钟的频繁顺序。 (= 我之前提到的孔)

有没有办法有效地做到这一点(因为行数很大)?

编辑:这是一个与之前不同的问题,所以如果不仔细阅读,请不要关闭它。

编辑: 当我每个工作日都有特定的早间和特定的晚间时如何应用它?

(这可以通过再次拆分为多索引来完成,然后选择最早和最晚日期,{步骤我不知道如何集成},然后在循环结束时合并结果时间索引。)但是如何将这一步整合到弯曲的括号中? 我还没有在我的样本上测试它,但@Rob Raymond 的建议可能是我不知道如何融入工作日方法的步骤......

dfse = pd.DataFrame({"DATE":pd.date_range(start=datetime(2020,7,24),end=datetime(2020,7,25), freq="5min")})\
    .merge(dfgaps, how="left").loc[lambda df: df["value"].isna()]

【问题讨论】:

    标签: python pandas dataframe datetime time


    【解决方案1】:

    merge() 很容易实现

    1. 合成了一个有一些漏洞的数据帧
    2. 在较短的date_range() 上查找丢失的时间
    3. 输出显示它可以正常工作,因为它少于总孔数
    4. 添加索引 dffind 然后merge() 比没有索引要慢。显示时序和模拟行。加上找到的结果是缺失的子集,因为它只在 04:00 到 16:00 之间进行搜索
    import pandas as pd
    import random
    import time
    df = pd.DataFrame(
        [{'DATE':d, "value":random.randint(0,10)}
            for d in pd.date_range(start=datetime(2013,1,1),end=datetime(2020,3,24), freq="5min")\
             .union(pd.date_range(start=datetime(2020,4,1),end=datetime(2020,7,24), freq="5min"))
             .union(pd.date_range(start=datetime(2012,7,1),end=datetime(2012,7,2), freq="5min"))
    
        ])
    # randomly "remove" from dataset so there are gaps
    mask = df.index.isin([random.randint(0, len(df)) for r in range(10)])
    dfgaps = df.loc[~mask]
    
    # date_range which is all of the dates that exist in source dataframe
    start = time.time()
    dt = dfgaps["DATE"].dt.floor("D").unique()
    dr = None
    for i,d in enumerate(dt):
        # only expand in contiguous ranges
        if i==0 or (i<len(dt)-1 and d+np.timedelta64(1, "D")==dt[i+1]) or (d>dt[i-1]+np.timedelta64(1, "D")):
            temp = pd.date_range(start=d, end=d+(np.timedelta64(1, "D")-np.timedelta64(1, "m")), freq="5min")
            dr = temp if dr is None else dr.union(temp)
    # date_range to dataframe NB hour>=n and hour<=m to only find between desired times
    dffind = pd.DataFrame({"DATE":[t for t in dr if t.hour>=4 and t.hour<=16]})
    
    # pick out missing items from shorter start/end date
    dfse = dffind.merge(dfgaps, how="left", on="DATE").loc[lambda df: df["value"].isna()]
    print(f"Execution Time: {time.time() - start:.2f}s Rows:{len(df):,}")
    print(f"Missing:\n{df[mask].to_string(index=False)}\nFound:\n{dfse.to_string(index=False)}")
    
    

    输出

    Execution Time: 27.92s Rows:793,155
    Missing:
                   DATE  value
    2013-01-02 23:45:00      4
    2013-09-27 14:20:00      8
    2014-04-26 12:35:00      0
    2015-05-06 20:55:00      1
    2016-07-30 21:20:00      5
    2016-10-09 18:10:00      2
    2017-12-26 04:20:00      2
    2018-11-06 19:50:00      3
    2018-12-14 15:40:00      8
    2019-09-29 06:25:00      9
    Found:
                   DATE  value
    2013-09-27 14:20:00    NaN
    2014-04-26 12:35:00    NaN
    2017-12-26 04:20:00    NaN
    2018-12-14 15:40:00    NaN
    2019-09-29 06:25:00    NaN
    

    【讨论】:

    • 澄清一下:1.这是否只包括上面的“early_daytime”和“late_daytime”之间的值?这在大型索引(行的 mio)上效率如何?还是有更有效的方法?
    • 我不确定是否在同一轨道上。也许我忘了提:输入索引只包含特定的工作日。 (例如在某些情况下没有周末,在某些情况下只有周日或周二。
    • 在此示例中,2020/7/24 是 early_date,2020/7/25 是 late_date。相反,如果您希望在 04:00 和 08:00 之间进行,则在构建一组期望值时很容易做到。我相信merge() 比任何循环代码更有效率。如果将 DATE 设为索引而不是列,则会得到改进。更新您的问题,我很高兴更新答案
    • 聪明的想法^^ 所以 DATE 也可以是一个盘中列。 (当以这种方式使用多索引时,我猜也可以过滤掉特定的匹配项,你有一个想法如何做到这一点吗?)我现在会更新问题
    • @Iroquois_Pliskin 我已经更新了答案。它现在使用所有存在的日期作为源数据框,并在您想要查找的时间进行子选择
    猜你喜欢
    • 2010-12-02
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    • 2018-03-14
    相关资源
    最近更新 更多