Pandas 基于时间的平均值

Pandas timebased mean

我已经将不同的数据从 homeassistant 导入到 influx db,现在我将它放在 pandas 数据框中,我想获取 mean() 但它应该基于索引中的时间。

我选了一个小的 df 来测试,它看起来像这样:

                                   value
time                                   
2021-03-09 07:25:41.989791+00:00    0.0
2021-03-09 07:26:45.165453+00:00    0.0
2021-03-09 16:56:04.806150+00:00    1.0
2021-03-09 18:10:57.762609+00:00    0.0
2021-03-09 19:45:55.182860+00:00    1.0
2021-03-09 19:49:27.519186+00:00    0.0

所以这只是我家里的一盏灯。我想随着时间的推移平均。所以我可以看到有多少百分比的时间它是打开的。当它说 1 它应该是 1 直到下一个数据点。在此 df 中,平均值应该非常低,因为大多数时候灯是关闭的。它仅在 16:56:04 到 18:10:57 和 19:45:55 到 19:49:27 之间打开。所以它打开大约:1 小时 19 分钟,总记录时间为 12 小时 23 分钟。因此,灯亮的时间约为记录时间的 10%。

还有两个问题:

  1. 我的传感器的值不同于 1 和 0(例如温度)

    2.the天会变

我真的不知道如何开始,有人知道吗?

您可以计算每个值的持续时间(time_next - time,然后转换为秒),然后对每一天取加权平均值:

# calculate durations
df['date'] = df['time'].dt.date
df['time_next'] = df['time'].shift(-1).ffill()
df['duration_s'] = (df['time_next'] - df['time']).dt.seconds

# calculate weighted average by date
df.groupby('date').apply(
    lambda z: np.average(z['value'], weights=z['duration_s']))

输出:

date
2021-03-09    0.105416
dtype: float64

P.S。值可以是任意数字,当然不能只是二进制


更新:

为了正确处理多日系列,我们可以更改数据框,在每天结束时(或第二天开始时)使用当天看到的最后一个值添加记录。

例如,在原始 post 的示例数据中,2021-03-10 00:00:00 处的值为 0。这样,当天最后一条记录的持续时间将显示到当天结束前剩余的秒数,从而使我们的加权平均值计算正确。

这是在代码中如何完成的(这里我假设 time 是原始数据帧的索引):

# add day-end values
z = df.append(
    df.resample('1d', label='right').last().ffill()
).sort_index()

# calculate durations
z['duration_s'] = -z.index.to_series().diff(-1).dt.total_seconds()

# calculate weighted average by date
z.groupby(z.index.date).apply(
    lambda z: np.average(z['value'], weights=z['duration_s'])).dropna()