2017-08-30 76 views
1

考虑以下合成例:在熊猫,按日期从DatetimeIndex

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第一个问题:为什么会发生?我怎样才能避免它?

接下来,我试过的groupbyresample组合:

df.groupby('cat').resample('1d').agg({'val': 'mean'}) 

这里,该指数是正确的,但我无法同时运行meancount聚合。这是第二个问题:为什么

df.groupby('cat').resample('1d').agg({'val': ['mean', 'count']}) 

不起作用?

最后一个问题什么是干净的方法来得到一个汇总(使用这两种功能)查看date类型的指数?

回答

1

对于第一个问题,需要转换为datetime s的无数倍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 s为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 
    ... 
    ... 
+0

我检查时序和'floor'解决方案是最快的 - [这里](https://stackoverflow.com/a/45943387/2901002) – jezrael