【发布时间】:2021-04-03 00:19:40
【问题描述】:
对不起,令人困惑的标题。我正在尝试清理在不同时间间隔报告引擎小时数的数据集。我正在尝试检测和解决两种情况:
-
报告的发动机小时数少于上次记录的发动机小时数
-
两个日期之间报告的发动机小时数大于所述日期之间的小时差
Sampled Date Meter eng_hours_diff date_hours_diff 2017-02-02 5336 24 24 2017-02-20 5578 242 432 2017-02-22 5625 47 48 2017-03-07 5930 305 312 2017-05-16 6968 1038 1680 2017-06-01 7182 214 384 2017-06-22 7527 345 504 2017-07-10 7919 392 432 2017-07-25 16391 8472 360 2017-08-20 8590 -7801 624 2017-09-05 8827 237 384 2017-09-26 9106 279 504 2017-10-16 9406 300 480 2017-10-28 9660 254 288 2017-11-29 10175 515 768
如果出现上述两种情况中的任何一种,我想做的是重新编写 ['Meter'] 系列并取其周围点之间的平均值。
我认为这可能需要两个步骤,一个是消除由于发动机小时数大于日期之间的小时数而导致的任何不准确性,然后重新计算 ['eng_hours_diff'] 列并检查是否还有一些是负面的。
我计算的最后两列是这样的:
dfa['eng_hours_diff'] = dfa['Meter'].diff().fillna(24)
dfa['date_hours_diff'] = dfa['Sampled Date'].diff().apply(lambda x:str(x)).apply(lambda x: x.split(' ')[0]).apply(lambda x:x.replace('NaT',"1")).apply(lambda x: int(x)*24)
编辑: 好的,我想我已经到了某个地方,但还没有到那里..
dfa['MeterReading'] = [x if y>0 & y<z else 0 for x,y,z in
zip(dfa['Meter'],dfa['eng_hours_diff'], dfa['date_hours_diff'])]
编辑 2:
感谢比尔的回答,我离得更近了。
应用此函数将用零替换任何不符合条件的记录。然后我用 np.nan 替换这些零并使用 interpolate 方法。
我唯一缺少的是当它们也以 np.nan 形式出现时如何填写最后一个值,我正在寻找是否有外推方法。
这是一个功能,以防将来有人偶然发现类似的问题:
dfa['MeterReading'] = dfa['MeterReading'].replace({0:np.nan}).interpolate(method='polynomial', order=2, limit=5, limit_direction='both').bfill()
这是我最后遇到的问题。遗漏了两个值,但由于差值变为负数,它会丢弃所有 4 个值。
【问题讨论】:
-
如果你用
np.nan而不是零替换丢失的仪表读数,那么eng_hours_diff列也会产生nans而不是负值。制作一个单独的插值列,然后根据一些逻辑选择最终的填充值。 -
对于最后的填充,与其尝试用多项式进行推断(可能导致预测不佳),不如保持滚动平均小时/天值(或者可能只是全球平均小时数)天使用带有
ffill方法选项的fillna),然后使用它来线性推断数据的末尾? -
滚动均值也不错,事实上我可以在整个系列中都这样做,因为我真正关心的是那个日期的大概时间,最重要的是我想要删除胖手指条目,如 1000000 小时或小于前一个的条目。也许我可以简单地做一个 ffill() 然后滚动平均值
-
听起来不错。滚动平均值会很好,或者如果小时/天变化很大并且您想要更多响应过滤器,请查看exponentially-weighted moving average。
标签: python pandas time-series