【问题标题】:Resample as frequency not losing data within a short timedelta重采样频率不会在短时间内丢失数据增量
【发布时间】:2019-09-27 17:56:40
【问题描述】:

我有 10 分钟间隔的测量数据。 问题是有时时间间隔是 9min 59 seconds 或 10min 01 seconds ,有时我有一个缺失值,所以时间间隔是 20 分钟。

我希望代码执行以下操作: 重新采样 10 分钟的值(我已经实现了)。 问题是,间隔不是 10:00 分钟(9 分 59 秒或 10 分 01 秒)的测量值丢失了,我想保留这些数据。

这是我的测试代码:

import pandas as pd
import numpy as np
df = pd.DataFrame(columns=('Datetime','V_L1','V_H3_L1','V_H3_L1_in_P'))

df['Datetime'] = ['01.01.2012 00:00:00', '01.01.2012 00:10:01', '01.01.2012 00:29:59','01.01.2012 00:50:00']
df['V_L1'] = [219,219.7,np.nan,220.3]
df['V_H3_L1'] = [3,1,2.5, np.nan]
df['Datetime'] = pd.to_datetime(df['Datetime'])
df.set_index('Datetime')
df = df.set_index('Datetime').resample('600S').asfreq()

输出:

                  V_L1  V_H3_L1  V_H3_L1_in_P
Datetime                                         
2012-01-01 00:00:00  219.0      3.0           NaN
2012-01-01 00:10:00    NaN      NaN           NaN
2012-01-01 00:20:00    NaN      NaN           NaN
2012-01-01 00:30:00    NaN      NaN           NaN
2012-01-01 00:40:00    NaN      NaN           NaN
2012-01-01 00:50:00  220.3      NaN           NaN

希望的输出:

                  V_L1  V_H3_L1  V_H3_L1_in_P
Datetime                                         
2012-01-01 00:00:00  219.0      3.0           NaN
2012-01-01 00:10:00  219.7      1.0           NaN
2012-01-01 00:20:00    NaN      NaN           NaN
2012-01-01 00:30:00    NaN      2.5           NaN
2012-01-01 00:40:00    NaN      NaN           NaN
2012-01-01 00:50:00  220.3      NaN           NaN

因此,如果频率集(10 分钟、600 秒)的增量小于几秒 + 或 - 5 秒,我想保持数据接受。

【问题讨论】:

  • df = df.set_index('Datetime').resample('600S’).first()?也可以使用.mean().last()等。
  • 既然您似乎希望10:01 与:10 一起使用,而29:59 与:20 一起使用,看来您可能想要在重新采样之前执行df['Datetime'] = df.Datetime.dt.floor('10min')?否则,还有.ceil().round()
  • @ALollz,实际上希望的输出有一个错误的数据,我希望 29:59 舍入到 30!抱歉,我现在更正了希望的输出数据。

标签: python pandas


【解决方案1】:
df['Datetime'] = df['Datetime'].dt.round('min')
df = df.set_index('Datetime').resample('600S').asfreq()

将日期时间四舍五入到最接近的分钟,然后您可以设置索引并重新采样。

【讨论】:

  • 您的解决方案在考虑在一分钟内进行四舍五入时非常有效!根据问题描述,我认为这是最干净的解决方案,但我添加了另一个解决方案(不太漂亮),以便更通用地舍入到我想要的 10 分钟值。
【解决方案2】:

好吧,我写了一个不是很漂亮的函数(我必须假设),但它做了我想要它做的事情。由于我正在处理大量数据,我认为这可能是一种安全的方法。 基本上使用 if, elif 结构,该函数检查时间戳的分钟部分并根据其值决定舍入...(向上或向下),我很确定有更好的方法来解决,请分享如果你有一个。

  • 如果 >=55,则舍入到下一个完整小时,elif >=45 到 50,elif >=35 到 40 等等..

所以,代码是:

import datetime

def round_time(time):
    if time.minute>=55:
        if time.hour==23:
            rounded = time-datetime.timedelta(hours=time.hour,minutes=time.minute,seconds=time.second)+datetime.timedelta(hours=time.hour+1,minutes=0,seconds=0)
        else:
            rounded = time-datetime.timedelta(minutes=time.minute, seconds=time.second)+datetime.timedelta(hours=time.hour+1, minutes=0, seconds=0)
elif time.minute >=45:
        rounded = time-datetime.timedelta(minutes=time.minute, seconds=time.second)+datetime.timedelta(minutes=50)
    elif time.minute >=35:
        rounded = time-datetime.timedelta(minutes=time.minute, seconds=time.second)+datetime.timedelta(minutes=40)
    elif time.minute >=25:
        rounded = time-datetime.timedelta(minutes=time.minute, seconds=time.second)+datetime.timedelta(minutes=30)
    elif time.minute >=15:
        rounded = time-datetime.timedelta(minutes=time.minute, seconds=time.second)+datetime.timedelta(minutes=20)
    elif time.minute >=5:
        rounded = time-datetime.timedelta(minutes=time.minute, seconds=time.second)+datetime.timedelta(minutes=10)
    elif time.minute >=0:
        rounded = time-datetime.timedelta(minutes=time.minute, seconds=time.second)+datetime.timedelta(minutes=0)
    return rounded

df['Datetime'] = df['Datetime'].apply(lambda x: round_time(x))
df = df.set_index('Datetime').resample('600S').asfreq()

How do I round datetime column to nearest quarter hour

虽然上述线程上的解决方案没有解决 10 分钟的值,但它是一个很好的参考! (29min 仍被四舍五入为 20,而不是我希望的值,30)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-19
    • 2021-08-21
    • 2017-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-09
    • 2020-12-28
    相关资源
    最近更新 更多