如何使用Pandas按小时分组数据框,使用时间戳进行分组。

7
我可以帮助您进行翻译。以下是您需要翻译的内容:

我有一个数据框架结构,其索引为时间戳:

    neg neu norm    pol pos date
time                        
1520353341  0.000   1.000   0.0000  0.000000    0.000   
1520353342  0.121   0.879   -0.2960 0.347851    0.000   
1520353342  0.217   0.783   -0.6124 0.465833    0.000   

我从时间戳创建日期:

data_frame['date'] = [datetime.datetime.fromtimestamp(d) for d in data_frame.time]

结果:

    neg neu norm    pol pos date
time                        
1520353341  0.000   1.000   0.0000  0.000000    0.000   2018-03-06 10:22:21
1520353342  0.121   0.879   -0.2960 0.347851    0.000   2018-03-06 10:22:22
1520353342  0.217   0.783   -0.6124 0.465833    0.000   2018-03-06 10:22:22

我希望按小时分组,并获取所有值的平均值(除时间戳外),该时间戳应为组开始的小时。因此,这是我想要实现的结果:

    neg neu norm    pol pos
time                    
1520352000  0.027989    0.893233    0.122535    0.221079    0.078779
1520355600  0.028861    0.899321    0.103698    0.209353    0.071811

到目前为止,我最接近的方法是使用这个答案

data = data.groupby(data.date.dt.hour).mean()

结果:

    neg neu norm    pol pos
date                    
0   0.027989    0.893233    0.122535    0.221079    0.078779
1   0.028861    0.899321    0.103698    0.209353    0.071811

但是我无法想出如何保留时间戳,以便考虑到分组开始时的小时。
3个回答

21

我在发布我的按小时四舍五入解决方案后,偶然发现了这个宝石,pd.DataFrame.resample

# Construct example dataframe
times = pd.date_range('1/1/2018', periods=5, freq='25min')
values = [4,8,3,4,1]
df = pd.DataFrame({'val':values}, index=times)

# Resample by hour and calculate medians
df.resample('H').median()

或者您可以使用 groupbyGrouper,如果您不想将时间作为索引:

df = pd.DataFrame({'val':values, 'times':times})
df.groupby(pd.Grouper(level='times', freq='H')).median()

非常整洁的答案。 - smerllo
如果数据框跨越多天,即不忽略日期时间索引的日期部分,则这些方法无法工作。问题中的原始方法 data = data.groupby(data.date.dt.hour).mean() 可以做到这一点,但确实不能保留小时数。在这种情况下,为了保留小时数,您可以从日期时间索引中提取小时数并将其放入单独的列中进行分组:data['hour']=data.index.hour - squarespiral

4

你是否尝试通过以下方式创建“小时”列:

data_frame['hour'] = data_frame.date.dt.hour

然后按小时分组,例如:

data = data.groupby(data.hour).mean()

是的,那给了我现在拥有的相同结果。问题在于保留/生成整点开始的时间戳。 - Franco

2

您可以将时间戳列向下舍入到最近的小时:

import math
df.time = [math.floor(t/3600) * 3600 for t in df.time]

甚至更简单的方法是使用整数除法:
df.time = [(t//3600) * 3600 for t in df.time]

您可以按照此列进行分组,从而保留时间戳。

我怎么没想到这个?这个完美地运作了,是如此简单而优雅的解决方案。谢谢! - Franco
如果您已经有一个日期时间索引,您可以像这样将其向下舍入到小时:df.loc[df.index.floor('H')] - 这也适用于其他时间频率“D”,... - squarespiral

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