我有一个带有日期时间列的数据框。我想仅按时间部分进行分组并聚合,例如通过取平均值。
我知道我可以使用 pd.Grouper 按日期和时间进行分组,但它不能仅按时间工作。
假设我们有以下数据框:
import numpy as np
import pandas as pd
drange = pd.date_range('2019-08-01 00:00', '2019-08-12 12:00', freq='1T')
time = drange.time
c0 = np.random.rand(len(drange))
c1 = np.random.rand(len(drange))
df = pd.DataFrame(dict(drange=drange, time=time, c0=c0, c1=c1))
print(df.head())
drange time c0 c1
0 2019-08-01 00:00:00 00:00:00 0.031946 0.159739
1 2019-08-01 00:01:00 00:01:00 0.809171 0.681942
2 2019-08-01 00:02:00 00:02:00 0.036720 0.133443
3 2019-08-01 00:03:00 00:03:00 0.650522 0.409797
4 2019-08-01 00:04:00 00:04:00 0.239262 0.814565
在这种情况下,以下代码会引发 TypeError:
grouper = pd.Grouper(key='time', freq='5T')
grouped = df.groupby(grouper).mean()
我可以设置 key=drange
按日期和时间分组,然后:
- 重置索引
- 将新列转换为 float
- 带有 pd.cut 的垃圾箱
- 回到过去
- 最后分组然后聚合
...但我想知道是否有更干净的方法来达到相同的结果。
最佳答案
Series.dt.time
/DatetimeIndex.time
将时间返回为 datetime.time
。这不太好,因为 pandas 最适合 timedelta64
,因此您的 'time'
列将转换为 object
,失去所有日期时间功能。
您可以减去标准化日期以获得 timedelta
形式的时间,这样您就可以继续使用 pandas 的 datetime
工具。您可以将其地板
分组。
s = (df.drange - df.drange.dt.normalize()).dt.floor('5T')
df.groupby(s).mean()
<小时/>
c0 c1
drange
00:00:00 0.436971 0.530201
00:05:00 0.441387 0.518831
00:10:00 0.465008 0.478130
... ... ...
23:45:00 0.523233 0.515991
23:50:00 0.468695 0.434240
23:55:00 0.569989 0.510291
<小时/>
或者,如果您不确定floor
,这将获得与索引名称相同的输出
df['time'] = (df.drange - df.drange.dt.normalize()) # timedelta64[ns]
df.groupby(pd.Grouper(key='time', freq='5T')).mean()
关于python - Pandas:如何按日期时间列进行分组,仅使用时间并丢弃日期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58307634/