【问题标题】:Pandas DataFrame with MultiIndex: Group by year of DateTime level values带有 MultiIndex 的 Pandas DataFrame:按日期时间级别值的年份分组
【发布时间】:2016-01-25 17:18:19
【问题描述】:

我有一个带有多索引的 pandas 数据框,如下所示:

# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd

# multi-indexed dataframe
df = pd.DataFrame(np.random.randn(8760 * 3, 3))
df['concept'] = "some_value"
df['datetime'] = pd.date_range(start='2016', periods=len(df), freq='60Min')
df.set_index(['concept', 'datetime'], inplace=True)
df.sort_index(inplace=True)

控制台输出:

df.head()
Out[23]: 
                 0         1         2
datetime                              
2016      0.458802  0.413004  0.091056
2016     -0.051840 -1.780310 -0.304122
2016     -1.119973  0.954591  0.279049
2016     -0.691850 -0.489335  0.554272
2016     -1.278834 -1.292012 -0.637931

df.head()
    ...: df.tail()

Out[24]: 
                 0         1         2
datetime                              
2018     -1.872155  0.434520 -0.526520
2018      0.345213  0.989475 -0.892028
2018     -0.162491  0.908121 -0.993499
2018     -1.094727  0.307312  0.515041
2018     -0.880608 -1.065203 -1.438645

现在我想在“日期时间”级别创建年度总和。

我的第一次尝试如下,但这不起作用:

# sum along years
years = df.index.get_level_values('datetime').year.tolist()
df.index.set_levels([years], level=['datetime'], inplace=True)
df = df.groupby(level=['datetime']).sum()

这对我来说似乎也很繁重,因为这项任务可能很容易实现。

所以这是我的问题:如何获得“日期时间”级别的年度总和?有没有一种简单的方法可以通过将函数应用于 DateTime 级别值来实现这一点?

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    你可以通过multiindexyear的第二级groupby

    # -*- coding: utf-8 -*-
    import numpy as np
    import pandas as pd
    
    # multi-indexed dataframe
    df = pd.DataFrame(np.random.randn(8760  * 3, 3))
    df['concept'] = "some_value"
    df['datetime'] = pd.date_range(start='2016', periods=len(df), freq='60Min')
    df.set_index(['concept', 'datetime'], inplace=True)
    df.sort_index(inplace=True)
    print df.head() 
                                           0         1         2
    concept    datetime                                         
    some_value 2016-01-01 00:00:00  1.973437  0.101535 -0.693360
               2016-01-01 01:00:00  1.221657 -1.983806 -0.075609
               2016-01-01 02:00:00 -0.208122 -2.203801  1.254084
               2016-01-01 03:00:00  0.694332 -0.235864  0.538468
               2016-01-01 04:00:00 -0.928815 -1.417445  1.534218
    
    # sum along years
    #years = df.index.get_level_values('datetime').year.tolist()
    #df.index.set_levels([years], level=['datetime'], inplace=True)
    
    print df.index.levels[1].year
    [2016 2016 2016 ..., 2018 2018 2018]
    df = df.groupby(df.index.levels[1].year).sum()
    print df.head()
                   0           1          2
    2016  -93.901914  -32.205514 -22.460965
    2017  205.681817   67.701669 -33.960801
    2018   67.438355  150.954614 -21.381809
    

    或者你可以使用get_level_valuesyear

    df = df.groupby(df.index.get_level_values('datetime').year).sum()
    print df.head()
                   0           1          2
    2016  -93.901914  -32.205514 -22.460965
    2017  205.681817   67.701669 -33.960801
    2018   67.438355  150.954614 -21.381809
    

    【讨论】:

    • 谢谢!我已经尝试过使用 get_level_values() 的选项,但显然出了点问题。无论如何,你的回答拯救了我的一天! :)
    • 很高兴能帮到你!祝你好运!
    【解决方案2】:

    从您的示例数据开始:

    df = pd.DataFrame(np.random.randn(8760 * 3, 3))
    df['concept'] = "some_value"
    df['datetime'] = pd.date_range(start='2016', periods=len(df), freq='60Min')
    df.set_index(['concept', 'datetime'], inplace=True)
    

    您可以将groupby 应用于您的MultiIndexlevel

    df.groupby(pd.TimeGrouper(level='datetime', freq='A')).sum()
    

    得到:

                         0          1          2
    datetime                                    
    2016-12-31  100.346135 -71.673222  42.816675
    2017-12-31 -132.880909 -66.017010 -73.449358
    2018-12-31  -71.449710 -15.774929  97.634349
    

    pd.TimeGrouper 现在 (0.23) 已弃用;请改用pd.Grouper(freq=...)

    【讨论】:

    • 感谢您的回答!我不知道 TimeGrouper 选项,它似乎是一个非常有用的功能。不过,我接受了 jezraels 的回答,因为它也适用于非 DateTime 级别,而无需使用 year 属性。
    • 您的问题不是关于“日期时间级别”吗?
    • 是的,但如果我没记错的话,jezraels 的答案也适用于非日期时间级别,而您的答案仅限于这些级别(但仍然正确!)。还是不是这样?无论如何,再次感谢!
    • 例如,非日期时间级别没有“年份”属性。您也不能使用 DateTimeIndex 可用但不是日期时间属性的许多其他频率。此外,TimeGrouper 是 DateTimeIndexes 的原始预期解决方案,直到 Grouper 成为通用解决方案,包括日期时间索引和列。
    猜你喜欢
    • 2017-07-27
    • 2017-10-16
    • 2015-07-19
    • 1970-01-01
    • 1970-01-01
    • 2018-06-24
    • 2016-08-05
    • 2014-05-24
    相关资源
    最近更新 更多