【问题标题】:Pandas timebased meanPandas 基于时间的平均值
【发布时间】:2021-03-10 09:52:04
【问题描述】:

我已经将不同的数据从 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.日子会变的。

我真的不知道如何开始有没有人有想法?

【问题讨论】:

    标签: python pandas influxdb


    【解决方案1】:

    您可以计算每个值的持续时间(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
    

    附:值可以是任意数字,当然不仅仅是二进制


    更新:

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

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

    这是如何在代码中完成的(这里我假设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()
    

    【讨论】:

    • 非常感谢您的回答,非常感谢您的帮助。所以它对我有用,但我试图循环它,因为我认为像 30 个传感器,我得到一个“ZeroDivisionError:权重总和为零,无法标准化”。是因为一天只有 0 个值吗?还是因为有一天根本没有价值?如果灯在 2021-03-09 开启 (1) 并在 2021-03-11 关闭怎么办? 2021-03-10 会是 0(关闭)吗?
    • @wieluk 是的,这是一个很好的观点。该错误可能是由于加权平均值中的零权重导致除以零。如果您一天只有一条记录,则可能会发生这种情况,在这种情况下,应从该事件计算持续时间,直到该天结束。请参阅我的答案中的“更新”部分,了解应该在这些情况下正常工作的解决方案(以及您提到的其他情况,例如没有记录的日子)
    猜你喜欢
    • 2021-11-19
    • 2023-03-10
    • 1970-01-01
    • 2014-12-01
    • 2012-06-06
    • 1970-01-01
    • 2018-02-17
    • 1970-01-01
    • 2021-08-18
    相关资源
    最近更新 更多