Pandas 每 30 分钟计算一次平均值,间隔为 +-10 分钟

奇乔德沃托

我有一个这样的数据框:

df = pd.DataFrame(
    {
        "observation_time": ["2021-11-24 10:10:03+00:00", "2021-11-24 10:20:02+00:00", "2021-11-24 10:30:03+00:00", "2021-11-24 10:40:02+00:00", "2021-11-24 10:50:02+00:00", "2021-11-24 11:00:05+00:00", "2021-11-24 11:10:03+00:00", "2021-11-24 11:20:02+00:00", "2021-11-24 11:30:03+00:00", "2021-11-24 11:40:02+00:00"], 
        "temp": [7.22, 7.33, 7.44, 7.5, 7.5, 7.5, 7.44, 7.61, 7.67, 7.78]
    }
)
           observation_time  temp
0 2021-11-24 10:10:03+00:00  7.22
1 2021-11-24 10:20:02+00:00  7.33
2 2021-11-24 10:30:03+00:00  7.44
3 2021-11-24 10:40:02+00:00  7.50
4 2021-11-24 10:50:02+00:00  7.50
5 2021-11-24 11:00:05+00:00  7.50
6 2021-11-24 11:10:03+00:00  7.44
7 2021-11-24 11:20:02+00:00  7.61
8 2021-11-24 11:30:03+00:00  7.67
9 2021-11-24 11:40:02+00:00  7.78

这个数据框只是一个例子,不能保证数据框每 10 分钟有一个时间点,我可以每分钟或长时间没有数据。

我想从“00”开始每 30 分钟计算一次 +-10 分钟间隔的平均值,在本例中为“10:00:00”。

我试图使用Grouper

df.groupby(pd.Grouper(key="observation_time", freq="30Min", offset="0m", label="right")).mean()

这给了我这个结果:

                                temp
observation_time                   
2021-11-24 10:30:00+00:00  7.275000
2021-11-24 11:00:00+00:00  7.480000
2021-11-24 11:30:00+00:00  7.516667
2021-11-24 12:00:00+00:00  7.725000

从时间的角度来看这很好,但它当然会计算 30 分钟间隔内的平均值。

相反,我想以 +-10 分钟的间隔计算平均值。

例如,2021-11-24 10:30:00+00:00平均值是在temp之间的区间内的所有值中计算的,在这种情况下是,平均值是2021-11-24 10:20:00+00:002021-11-24 10:40:00+00:007.337.447.385

最终结果应该是这样的:

                               temp
observation_time                   
2021-11-24 10:30:00+00:00  7.385
2021-11-24 11:00:00+00:00  7.5
2021-11-24 11:30:00+00:00  7.64

任何的想法?谢谢

阿尔比耶托

编辑:下面的答案是假设每行对应一个 10 分钟的间隔。如果您有不均匀间隔的数据,我们必须手动对数据集进行 bin 以获得所需的输出:

import numpy as np

# the sampling will be computed in +/- 10 minutes from the bin
sampling_interval = np.timedelta64(10, 'm')

# get 30 minutes bins
bins_interval = "30min"
bins = df['observation_time'].dt.floor(bins_interval).unique()

avg_values = []
for grouped_bin in bins:
    # subset the dataframe in the binned intervals
    subset = df[df['observation_time'].between(
        grouped_bin - sampling_interval, 
        grouped_bin + sampling_interval
    )]
    
    avg_values.append({
        'observation_time': grouped_bin,
        'temp': subset['temp'].mean()
    })

averaged_df = pd.DataFrame(avg_values)

我不确定这是最“pythonic”的方式,但我会这样处理问题:

# we create an empty dictionary in which we'll store the computed avgs
# to turn into a DataFrame later
avg_values = []

# we iterate over the DataFrame starting at index 1 and skipping 3 rows at a time
for idx in range(1, len(df.index), 3):
    # store the observation time in a separate variable
    observation_time = df.loc[idx, 'observation_time']
    # compute the mean between the rows before the current one, the
    # current one, and the next one
    avg_in_interval = np.nanmean([
        df.loc[idx-1, 'temp'] if idx > 0 else np.nan,
        df.loc[idx, 'temp'],
        df.loc[idx+1, 'temp'] if idx < len(df.index)-1 else np.nan
    ])
    # we append the two variables to the dictionary
    avg_values.append({'observation_time': observation_time, 'temp': avg_in_interval})

# new DataFrame
averaged_df = pd.DataFrame(avg_values)

或者,以更紧凑和通用的方式,因此您可以配置平均的间隔宽度,

interval_width = 3 # assuming it is an odd number
starting_idx = interval_width // 2
avg_values = []

for idx in range(starting_idx, len(df.index), interval_width):
    avg_values.append({
        'observation_time': df.loc[idx, 'observation_time'],
        'temp': np.mean(df.iloc[idx-starting_idx:idx+starting_idx]['temp'])
    })

averaged_df = pd.DataFrame(avg_values)

你也可以把它变成一个函数来保持你的代码干净:

def get_averaged_df(df, interval_width: int):
    if interval_width % 2 == 0:
        raise Error("interval_width must be an odd integer")

    starting_idx = interval_width // 2
    avg_values = []

    for idx in range(starting_idx, len(df.index), interval_width):
        avg_values.append({
            'observation_time': df.loc[idx, 'observation_time'],
            'temp': np.mean(df.iloc[idx-starting_idx:idx+starting_idx]['temp'])
        })

    return pd.DataFrame(avg_values)


averaged_df = get_averaged_df(df, 3)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用dplyr或aggregte函数每10分钟计算一次几何平均值

Windows 10每30分钟冻结一次

RRDtool的设置间隔为5分钟,但每30分钟发送一次数据吗?

MATLAB:在串行时间内每 5 分钟计算一次平均值

每 30 分钟清空一次垃圾桶

Cronjob每30分钟运行一次

如何获取从当前时间到晚上10:30的每30:00(30分钟)的时间间隔

MySQL窗口函数每5分钟计算一次平均值或最大值

MYSQL每10分钟获取一列的平均值

30分钟之前每5分钟执行一次Cron工作

在 30 分钟内每 5 分钟检查一次循环中的特定进程

每 N 分钟运行一次,或者如果项目与平均值不同

对Cronjob的理解:如何每天每10和30分钟从8-10到10-30运行?

Windows 10 每 5 分钟让我注销一次

BroadcastReceiver 活动 Observable 与每 10 分钟检查一次

如何每 10 分钟错开一次循环

如何在 Jmeter 每 20-30 分钟后增加 10-20% 的负载

每 10 分钟执行一次函数,最后 5 分钟

每天每 30 分钟运行一次测试,每年运行 365 次

如何创建每 30 分钟提醒我一次的通知?

Windows Insider 服务每 30 分钟自动启动一次,导致 mysql 崩溃

如何每 30 分钟更新一次我的 Service Worker 中的缓存文件?

让cron作业每30分钟运行一次-使用cron.hourly?

节点JS:如何每30分钟运行一次任务,包括现在

我如何每30分钟执行一次cron作业?

如何每20和30分钟更新一次价值?

如何在Linux Mint上每30分钟自动显示一次桌面

Surface Pro 6每30分钟运行一次待机(SC_MONITORPOWER)

在Swift中每30分钟发送一次位置更新