我有一个带有多索引的数据框,其中包含一个名为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()
这看起来非常简洁,因此,如果可以优雅地进行拆分,那也将回答我的问题。
答案 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
如果输入数据已经在datetimeindex
中MultiIndex
:
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