代码之家  ›  专栏  ›  技术社区  ›  dirk

Pandas:数据帧分组年/月并返回新的DatetimeIndex

  •  8
  • dirk  · 技术社区  · 8 年前

    我需要一些熊猫分组的指导 DateFrame 按年或月创建对象,并返回一个新的 日期框架 具有新索引的对象。 这是我迄今为止的代码。 groupby 按照预期工作。

    从.csv文件加载数据,解析“日期”到日期格式(finance.yahoo.com的历史股票报价)

    In [23]: import pandas as pd
             file = pd.read_csv("sdf.de.csv", parse_dates=['Date'])
             file.head(2)
    
    Out[23]:
        Date        Open    High    Low     Close   Volume  Adj Close
    0   2016-02-16  18.650  18.70   17.940  18.16   1720800 17.0600
    1   2016-02-15  18.295  18.64   18.065  18.50   1463500 17.3794
    

    按“日期”升序排序文件,并将索引设置为 Date

    In [24]: daily = file.sort_values(by='Date').set_index('Date')
             daily.head()
    
    Out[24]:
                Open    High    Low     Close   Volume  Adj Close
    Date                        
    2000-01-03  14.20   14.50   14.15   14.40   277400  2.7916
    2000-01-04  14.29   14.30   13.90   14.15   109200  2.7431
    

    月份分组

    我会再做一次 apply() 将特定组的数据进行浓缩,例如找到最高的 High 年/月的值或 sum() 这个 Volume 价值观本例省略了该步骤。

    In [39]: monthly = daily.groupby(lambda x: (x.year, x.month))
             monthly.first()
    
    Out[39]:
                Open    High    Low     Close   Volume  Adj Close
    (2000, 1)   14.200  14.500  14.150  14.400  277400  2.7916
    (2000, 2)   13.900  14.390  13.900  14.250  287200  2.7625
    ... ... ... ... ... ... ...
    (2016, 1)   23.620  23.620  23.620  23.620  0       22.1893
    (2016, 2)   19.575  19.630  19.140  19.450  1783000 18.2719
    

    这是有效的,但它给了我一个 日期框架 以元组为索引的对象。

    期望的结果,在本例中为月分组,将是一个全新的结果 DataFrame 对象,但 日期 索引应该是新的 DatetimeIndex 形式为 %Y-%m 或者只是 %Y 如果按年份分组。

    Out[39]:
            Open    High    Low     Close   Volume  Adj Close
    Date
    2000-01 14.200  14.500  14.150  14.400  277400  2.7916
    2000-02 13.900  14.390  13.900  14.250  287200  2.7625
    ... ... ... ... ... ... ...
    2016-01 23.620  23.620  23.620  23.620  0       22.1893
    2016-02 19.575  19.630  19.140  19.450  1783000 18.2719
    

    我感谢你的指点。

    2 回复  |  直到 8 年前
        1
  •  10
  •   jezrael    8 年前

    您可以使用 groupby 具有 daily.index.year, daily.index.month 或更改 index to_period 然后 子句 通过 指数 :

    print daily
                  Open   High    Low  Close   Volume  Adj Close
    Date                                                       
    2000-01-01  14.200  14.50  14.15  14.40   277400     2.7916
    2000-02-01  13.900  14.39  13.90  14.25   287200     2.7625
    2016-01-01  23.620  23.62  23.62  23.62        0    22.1893
    2016-02-01  19.575  19.63  19.14  19.45  1783000    18.2719
    
    print daily.groupby([daily.index.year, daily.index.month]).first()
              Open   High    Low  Close   Volume  Adj Close
    2000 1  14.200  14.50  14.15  14.40   277400     2.7916
         2  13.900  14.39  13.90  14.25   287200     2.7625
    2016 1  23.620  23.62  23.62  23.62        0    22.1893
         2  19.575  19.63  19.14  19.45  1783000    18.2719
    
    daily.index = daily.index.to_period('M')
    print daily.groupby(daily.index).first()
               Open   High    Low  Close   Volume  Adj Close
    Date                                                    
    2000-01  14.200  14.50  14.15  14.40   277400     2.7916
    2000-02  13.900  14.39  13.90  14.25   287200     2.7625
    2016-01  23.620  23.62  23.62  23.62        0    22.1893
    2016-02  19.575  19.63  19.14  19.45  1783000    18.2719
    
        2
  •  2
  •   Alexander    8 年前

    您可以使用列表理解来访问时间戳中的年和月访问变量,然后对其进行分组。

    >>> df.groupby([[d.year for d in df.Date], [d.month for d in df.Date]]).first()
                 Date    Open   High    Low  Close   Volume  Adj_Close
    2000 1 2000-01-01  14.200  14.50  14.15  14.40   277400     2.7916
         2 2000-02-01  13.900  14.39  13.90  14.25   287200     2.7625
    2016 1 2016-01-01  23.620  23.62  23.62  23.62        0    22.1893
         2 2016-02-01  19.575  19.63  19.14  19.45  1783000    18.2719