是否有一种方法可以在熊猫时间框架中找到不从偶数小时开始的小时平均值?



我有一个大约每10秒用时间戳索引一次的pandas数据框架(python)。我想找到小时平均值,但我找到的所有函数都以偶数小时开始平均(例如,小时9包括从08.00:00到08:59:50的数据)。假设我有下面的数据框。

Timestamp              value    data   
2022-01-01 00:00:00    0.0      5.31
2022-01-01 00:00:10    0.0      0.52
2022-01-01 00:00:20    1.0      9.03
2022-01-01 00:00:30    1.0      4.37
2022-01-01 00:00:40    1.0      8.03
... 
2022-01-01 13:52:30    1.0      9.75
2022-01-01 13:52:40    1.0      0.62
2022-01-01 13:52:50    1.0      3.58
2022-01-01 13:53:00    1.0      8.23
2022-01-01 13:53:10    1.0      3.07
Freq: 10S, Length: 5000, dtype: float64 

那么我要做的是:

  1. 只看那些持续1小时的数据值为1的数据
  2. 找到这些小时的每小时平均值(例如,可以在01:30:00-02:29:50和11:16:30 - 12:16:20之间)。

我希望我把问题讲清楚了。我该怎么做呢?

编辑:

也许这个问题的措辞有点不清楚。我增加了第三列data,这是我想求的均值。我只对value = 1持续一小时的时间间隔感兴趣,其余的数据可以排除。

编辑# 2:

我的问题的一点背景:我有一个传感器给我每10秒的数据。对于待"批准"的数据;某些需求是要满足的(在这个例子中是value),我需要每小时的平均值(最好是发生这种情况的时间戳)。因此,为了将可能包含在我的分析中的小时数最大化,我希望找到完整的小时数,即使它们不是在偶数时间戳开始的。

如果我理解正确,你想要一个条件平均值-计算data列的每小时平均值条件value列上,每10秒行1

假设您的数据框名为df,执行此操作的步骤如下:

创建分组列

这是您的"小时"列,可以通过

创建
df['hour'] = df.Timestamp.hour
<<p>

创建条件/strong>现在我们有了一个列来标识组,我们可以检查哪些组符合条件-只有那些value始终等于1的组。如果我们有10秒的间隔,并且是每小时,那么如果我们按小时分组,然后这一列,那么我们应该得到360,因为每小时有360个10秒的间隔。

分组计算

现在可以对aggregate函数进行分组和使用:

  • value列求和,根据条件
  • 求值
  • 计算data列返回的有效小时数的平均值
# group and aggregate
df_mean = df[['hour', 'value', 'data']].groupby('hour').aggregate({'value': 'sum', 'data': 'mean'})
# apply condition
df_mean = df_mean[df_mean['value'] == 360]

就是这样-你剩下的数据帧包含data的平均值,只有在你有完整的value=1小时的时候。

如果你想增加这一列,这样你就不必从08:00:00-09:00:00开始按小时分组,也许你想从08:00:10-09:00:10开始,那么解决方案很简单-增加分组列,但在此过程中不改变任何其他内容。

为了做到这一点,你可以使用datetime.timedelta来向前或向后移动东西,这样df.Timestamp.hour仍然可以利用来保持事情简单。

从数据推断分组

最后一个想法——如果你想推断在滚动的基础上你有完整的数据,那么你可以用滚动和来做——这更容易。你:

  • 计算value的滚动和和data的平均值
  • 只选择value等于360的地方
df_roll = df.rolling(360).aggregate({'value': 'sum', 'data': 'mean'})
df_roll = df_roll[df_roll['value'] == 360]

是的,有。你需要resampleoffset

制作一些测试数据

请确保下次提供有意义的测试数据。

import pandas as pd
import numpy as np
# One day in 10 second intervals
index = pd.date_range(start='1/1/2018', end='1/2/2018', freq='10S')
df = pd.DataFrame({"data": np.random.random(len(index))}, index=index)
# This will set the first part of the data to 1, the rest to 0
df["value"] = (df.index < "2018-01-01 10:00:10").astype(int)

结果如下:

>>> df 
data  value
2018-01-01 00:00:00  0.377082      1
2018-01-01 00:00:10  0.574471      1
2018-01-01 00:00:20  0.284629      1
2018-01-01 00:00:30  0.678923      1
2018-01-01 00:00:40  0.094724      1
...                       ...    ...
2018-01-01 23:59:20  0.839973      0
2018-01-01 23:59:30  0.890321      0
2018-01-01 23:59:40  0.426595      0
2018-01-01 23:59:50  0.089174      0
2018-01-02 00:00:00  0.351624      0

用偏移量

获取每小时的平均值下面是一个小函数,检查片中所有value行是否都等于1,如果等于,则返回mean,否则(隐式)返回None

def get_conditioned_average(frame):
if frame.value.eq(1).all():
return frame.data.mean()

现在只需将此应用于每小时切片,例如,在整小时后10秒开始。

df2 = df.resample('H', offset='10S').apply(get_conditioned_average)

这是最后的结果:

>>> df2
2017-12-31 23:00:10    0.377082
2018-01-01 00:00:10    0.522144
2018-01-01 01:00:10    0.506536
2018-01-01 02:00:10    0.505334
2018-01-01 03:00:10    0.504431
...             ...         ...
2018-01-01 19:00:10         NaN
2018-01-01 20:00:10         NaN
2018-01-01 21:00:10         NaN
2018-01-01 22:00:10         NaN
2018-01-01 23:00:10         NaN
Freq: H, dtype: float64

最新更新