从日期时间多索引级别开始按时间分组的熊猫

时间:2020-10-19 11:24:49

标签: python pandas pandas-groupby multi-index

我有一个带有多索引的数据框,其中包含一个名为datetime的级别DatetimeIndex。我想按一天中的时间对数据进行分组。通过

这样做是不是很习惯?
df.groupby(df.index.get_level_values('datetime').time).something()

?我问是因为我不喜欢.get_level_values('datetime')部分。特别是:如果datetime不是索引的一部分,我可以更轻松地编写

df.groupby(df.datetime.dt.time).something()

我的印象是,将列视为索引的目的是使此类操作更直接,所以我感到惊讶,这里的情况恰恰相反。

编辑: 我意识到,如果可以轻松地将我的datetime级别分为date级别和time级别,我可以做到

# change df.index to have levels [date, time, x, y, z] instead of [datetime, x, y, z]
df.groupby(level='time').something()

这看起来非常简洁,因此,如果可以优雅地进行拆分,那也将回答我的问题。

1 个答案:

答案 0 :(得分:1)

这样做是惯用的吗

df.groupby(df.index.get_level_values('datetime').time).median()

我想是的,如果想要MultiIndex级别的属性,例如这里的DatetimeIndex.time,带有级别名称。

您还可以按位置使用选择级别-这里是第一级:

df.groupby(df.index.get_level_values(0).time).median()

您的编辑解决方案应该简化:

df.groupby(level='time').median()
df.groupby(level=1).median()
#some functions like sum, mean, median
df.median(level=1)

编辑:

如果可能,最简单的方法是将值拆分为日期和时间,然后创建MultiIndex

df = pd.DataFrame({
        'datetime': pd.to_datetime(['2000-01-05 15:00:00'] * 3 + ['2000-01-06'] * 3),
         'x':[4,5,4,5,5,4],
         'y':[7] * 6,
         'z':[1,3] * 3,
         'col':[5,3,6,9,2,4]
})

df['date'] = df['datetime'].dt.date
df['time'] = df['datetime'].dt.time

df = df.set_index(['date','time','x','y','z']).drop('datetime', axis=1)
print (df)
                           col
date       time     x y z     
2000-01-05 15:00:00 4 7 1    5
                    5 7 3    3
                    4 7 1    6
2000-01-06 00:00:00 5 7 3    9
                        1    2
                    4 7 3    4
                    

如果输入数据已经在datetimeindexMultiIndex

df1 = pd.DataFrame({
        'datetime': pd.to_datetime(['2000-01-05 15:00:00'] * 3 + ['2000-01-06'] * 3),
         'x':[4,5,4,5,5,4],
         'y':[7] * 6,
         'z':[1,3] * 3,
         'col':[5,3,6,9,2,4]
}).set_index(['datetime','x','y','z'])

print (df1)
                           col
datetime            x y z     
2000-01-05 15:00:00 4 7 1    5
                    5 7 3    3
                    4 7 1    6
2000-01-06 00:00:00 5 7 3    9
                        1    2
                    4 7 3    4

names = ['date','time','x','y','z']
df1.index = pd.MultiIndex.from_tuples([(d.date(), d.time(),a,b,c) 
                                       for d,a,b,c in df1.index], names=names)
print (df1)
                           col
date       time     x y z     
2000-01-05 15:00:00 4 7 1    5
                    5 7 3    3
                    4 7 1    6
2000-01-06 00:00:00 5 7 3    9
                        1    2
                    4 7 3    4