考虑以下合成示例:
import pandas as pd
import numpy as np
np.random.seed(42)
ix = pd.date_range('2017-01-01', '2017-01-15', freq='1H')
df = pd.DataFrame(
{
'val': np.random.random(size=ix.shape[0]),
'cat': np.random.choice(['foo', 'bar'], size=ix.shape[0])
},
index=ix
)
产生以下形式的表格:
cat val
2017-01-01 00:00:00 bar 0.374540
2017-01-01 01:00:00 foo 0.950714
2017-01-01 02:00:00 bar 0.731994
2017-01-01 03:00:00 bar 0.598658
2017-01-01 04:00:00 bar 0.156019
现在,我想计算每个类别和日期的实例的数量和平均值。
以下groupby
几乎是完美的:
df.groupby(['cat',df.index.date]).agg({'val': ['count', 'mean']})
返回:
val
count mean
cat
bar 2017-01-01 16 0.437941
2017-01-02 16 0.456361
2017-01-03 9 0.514388...
这个问题的一个问题是索引的第二级转换为字符串而不是date
。 第一个问题:为什么会这样?我怎么能避免它?
接下来,我尝试了groupby
和resample
的组合:
df.groupby('cat').resample('1d').agg({'val': 'mean'})
此处,索引是正确的,但我无法同时运行mean
和count
聚合。这是第二个问题:为什么
df.groupby('cat').resample('1d').agg({'val': ['mean', 'count']})
不能工作吗?
上一个问题为索引获取聚合(使用两个函数)视图和以及date
类型的简洁方法是什么?
答案 0 :(得分:2)
对于第一个问题,需要转换为datetime
,而不是like:
df1 = df.groupby(['cat',df.index.floor('d')]).agg({'val': ['count', 'mean']})
#df1 = df.groupby(['cat',df.index.normalize()]).agg({'val': ['count', 'mean']})
#df1 = df.groupby(['cat',pd.to_datetime(df.index.date)]).agg({'val': ['count', 'mean']})
print (df1.index.get_level_values(1))
DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04',
'2017-01-05', '2017-01-06', '2017-01-07', '2017-01-08',
'2017-01-09', '2017-01-10', '2017-01-11', '2017-01-12',
'2017-01-13', '2017-01-14', '2017-01-01', '2017-01-02',
'2017-01-03', '2017-01-04', '2017-01-05', '2017-01-06',
'2017-01-07', '2017-01-08', '2017-01-09', '2017-01-10',
'2017-01-11', '2017-01-12', '2017-01-13', '2017-01-14',
'2017-01-15'],
dtype='datetime64[ns]', freq=None)
...因为date
是python对象:
df1 = df.groupby(['cat',df.index.date]).agg({'val': ['count', 'mean']})
print (type(df1.index.get_level_values(1)[0]))
<class 'datetime.date'>
第二个问题 - 我认为它是错误或尚未实现,因为仅在agg
中使用一个函数名称:
df2 = df.groupby('cat').resample('1d')['val'].agg('mean')
#df2 = df.groupby('cat').resample('1d')['val'].mean()
print (df2)
cat
bar 2017-01-01 0.437941
2017-01-02 0.456361
2017-01-03 0.514388
2017-01-04 0.580295
2017-01-05 0.426841
2017-01-06 0.642465
2017-01-07 0.395970
2017-01-08 0.359940
...
...
但与apply
合作old way:
df2 = df.groupby('cat').apply(lambda x: x.resample('1d')['val'].agg(['mean','count']))
print (df2)
mean count
cat
bar 2017-01-01 0.437941 16
2017-01-02 0.456361 16
2017-01-03 0.514388 9
2017-01-04 0.580295 12
2017-01-05 0.426841 12
2017-01-06 0.642465 7
2017-01-07 0.395970 11
2017-01-08 0.359940 9
2017-01-09 0.564851 12
...
...