我在 python 中有一个基本的 pandas 数据框,它接收数据并绘制折线图。每个数据点都涉及一个时间。如果数据文件一切正常,理想情况下每个时间戳彼此相差大约 30 分钟。在某些情况下,超过一小时没有数据通过。在这些时间里,我想将此时间范围标记为“缺失”并绘制一个不连续的折线图,公然显示数据缺失的位置。
由于问题非常具体,我很难弄清楚如何执行此操作甚至搜索解决方案。数据是“实时”的,它会不断更新,因此我不能只查明某个区域并进行编辑作为解决方法。
看起来像这样的东西:
用于创建日期时间列的代码:
#convert first time columns into one datetime column
df['datetime'] = pd.to_datetime(df[['year', 'month', 'day', 'hour', 'minute', 'second']])
我已经弄清楚了如何计算时差,这涉及到创建一个新列。 这是以防万一的代码:
df['timediff'] = (df['datetime']-df['datetime'].shift().fillna(pd.to_datetime("00:00:00", format="%H:%M:%S")))
基本了解数据框:
datetime l1 l2 l3
2019-02-03 01:52:16 0.1 0.2 0.4
2019-02-03 02:29:26 0.1 0.3 0.6
2019-02-03 02:48:03 0.1 0.3 0.6
2019-02-03 04:48:52 0.3 0.8 1.4
2019-02-03 05:25:59 0.4 1.1 1.7
2019-02-03 05:44:34 0.4 1.3 2.2
我只是不确定如何着手创建涉及时差的不连续“实时”情节。
提前致谢。
最佳答案
不完全是您想要的,但一种快速而优雅的解决方案是对数据重新采样。
df = df.set_index('datetime')
df
l1 l2 l3
datetime
2019-02-03 01:52:16 0.1 0.2 0.4
2019-02-03 02:29:26 0.1 0.3 0.6
2019-02-03 02:48:03 0.1 0.3 0.6
2019-02-03 04:48:52 0.3 0.8 1.4
2019-02-03 05:25:59 0.4 1.1 1.7
2019-02-03 05:44:34 0.4 1.3 2.2
df.resample('30T').mean()['l1'].plot(marker='*')
如果您绝对需要精确绘制每个样本,您可以在连续时间戳之间的差异超过某个阈值的地方拆分数据,并分别绘制每个 block 。
from datetime import timedelta
# get difference between consecutive timestamps
dt = df.index.to_series()
td = dt - dt.shift()
# generate a new group index every time the time difference exceeds
# an hour
gp = np.cumsum(td > timedelta(hours=1))
# get current axes, plot all groups on the same axes
ax = plt.gca()
for _, chunk in df.groupby(gp):
chunk['l1'].plot(marker='*', ax=ax)
或者,您可以在数据中注入(inject)“漏洞”。
# find samples which occurred more than an hour after the previous
# sample
holes = df.loc[td > timedelta(hours=1)]
# "holes" occur just before these samples
holes.index -= timedelta(microseconds=1)
# append holes to the data, set values to NaN
df = df.append(holes)
df.loc[holes.index] = np.nan
# plot series
df['l1'].plot(marker='*')
关于python - 计算时间差,如果差值大于一个小时,标记为 'missing' ,在该区域的折线图中绘制差距,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54951663/