【问题标题】:In pandas, group by date from DatetimeIndex在熊猫中,从 DatetimeIndex 按日期分组
【发布时间】:2017-08-30 15:59:02
【问题描述】:

考虑以下综合示例:

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

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    对于第一个问题需要转换为datetimes 没有时间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)
    

    ...因为dates 是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
    ...
    ... 
    

    old wayapply 一起工作:

    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
        ...
        ...
    

    【讨论】:

    • 我检查了时间,floor 解决方案最快 - here
    猜你喜欢
    • 2020-07-10
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    • 2018-04-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-24
    相关资源
    最近更新 更多