2017-08-30 59 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