Pandas:将日期分组为30分钟间隔并计算平均值。

6

我有一个Pandas数据框,其中包含两列: speedtime

speed   date
54.72   1:33:56
49.37   1:33:59
37.03   1:34:03
24.02   7:39:58
28.02   7:40:01
24.04   7:40:04
24.02   7:40:07
25.35   7:40:10
26.69   7:40:13
32.04   7:40:16
28.02   11:05:43
30.71   11:05:46
29.36   11:05:49
18.68   11:05:52
54.72   11:05:55
34.69   10:31:34
25.03   10:31:38
56.04   10:31:40
44.03   10:31:43

我想计算每个30分钟速度区间的平均值。例如,第4个区间(1:31-2:00)的平均速度为(54.72+49.37+37.03)/3。我考虑将小时、分钟和秒转换为从00:00开始的秒数,然后将其分成1800秒的区间。我尝试使用scipy.stats中的binned_statistic,但我的主要问题是无法找到一种基于日期分隔区间并获取速度平均值的方法。
有什么想法吗?

你到目前为止尝试了什么? - norok2
@norok2 我尝试使用 scipy.stats 中的 binned_statistic,但我无法找到一种基于日期分隔箱并获取速度平均值的方法。 https://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.binned_statistic.html - manosbar
可能是Python Pandas中按对象分组的时间差的重复问题。 - Nihal
@Nihal 我主要的问题是我在上面回答过并现在已经添加到问题描述中。无论如何,感谢您的评论。 - manosbar
1
这个问题非常有用,特别是hellpander的回答,但你应该在标题中提到它与根据“日期”列进行分箱有关。否则没有人会找到它。 - HerrIvan
2个回答

19

使用 pandas.Grouper + 偏移量别名 进行日期时间转换:

df['date'] = pd.to_datetime(df.date)
df.groupby(pd.Grouper(key='date', freq='30min')).mean().dropna()

    speed
date    
2018-09-20 01:30:00     47.040000
2018-09-20 07:30:00     26.311429
2018-09-20 10:30:00     39.947500
2018-09-20 11:00:00     32.298000

1
一个好的解决方案。唯一需要小心的是,您正在使用datetime来表示实际上没有与之关联的date的变量。虽然pd.Grouper可以使用datetime给出所需的bins,但是当使用timedelta时,它会创建完全不同的bins(从您的Series中的第一个timedelta开始),因此可能会有些不可预测。 - ALollz
2
是的,您的解决方案更加简洁。 - hellpanderr
1
我认为这很棒,而且投票结果也明确表明了这一点。但是我发现pandas内置的日期分箱方法在确定箱子是否从某些“合理”的边缘(即从00:00:00开始)或从您的Series中最早的测量值开始时不太一致。这似乎在这里发生了,只是从datetime更改为timedelta,这真是遗憾。 - ALollz
我相信这是最好的解决方案。我还保留了@ALollz在下面回答中提到的pd.to_timedelta,因为我不想让今天的日期出现在我的输出中。 - manosbar

6

由于你的date列实际上不是日期,将其转换为timedelta可能更合理,这样就不会与日期相关联。

然后,你可以使用dt.floor将其分组为30分钟的区间。

import pandas as pd

df['date'] = pd.to_timedelta(df.date)
df.groupby(df.date.dt.floor('30min')).mean()

输出:

              speed
date               
01:30:00  47.040000
07:30:00  26.311429
10:30:00  39.947500
11:00:00  32.298000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接