【问题标题】:Pandas: DataFrame groupby for year/month and return with new DatetimeIndex熊猫:年/月的DataFrame groupby并返回新的DatetimeIndex
【发布时间】:2016-05-31 01:23:59
【问题描述】:

我需要一些指导来按年或月对 Pandas DateFrame 对象进行分组,并返回一个带有新索引的新 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

这可行,但它给了我一个带有元组作为索引的DateFrame 对象。

在这种情况下,对于月份分组,期望的结果将是一个全新的DataFrame 对象,但Date 索引应该是%Y-%m 形式的新DatetimeIndex 或只是%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

我很感谢任何指示。

【问题讨论】:

  • 欢迎来到堆栈溢出。您可以查看tour
  • 谢谢,但为什么呢?我的问题有问题吗?
  • 不,问题很好。没问题。
  • 啊,好的。可以,但尚未测试建议的解决方案。

标签: python pandas datetimeindex


【解决方案1】:

您可以使用列表推导从时间戳中访问年份和月份访问器变量,然后对它们进行分组。

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

【讨论】:

    【解决方案2】:

    您可以将groupbydaily.index.year, daily.index.month 一起使用,或者将index to_period 然后groupby 更改为index

    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
    

    【讨论】:

    • 谢谢,最后一个例子完美运行。但奇怪的是,如果我重新运行此单元格,我会收到一个属性错误----> 4 daily.index = daily.index.to_period('M') 5 monthly = daily.groupby(daily.index).first() 6 print (monthly) AttributeError: 'PeriodIndex' object has no attribute 'to_period' 我必须重新运行 所有 个单元格才能使其正常工作
    • IIUC 您只需将PeriodIndex 设置为一次daily.index = daily.index.to_period('M'),然后使用其他代码。尝试测试:print dailydaily.index = daily.index.to_period('M')print daily
    • 但它永久更改了dailyPeriodIndex。如果我想将其改回 daily.index = daily.index.to_period('D')for 天或进一步使用 daily.index = daily.index.to_period('A')for 年,我会收到 AttributeError
    • 那么也许最好使用列而不是索引,例如:daily['m'] = daily.index.to_period('M')monthly = daily.groupby('m').first(),然后是 daily['d'] = daily.index.to_period('D')daily1 = daily.groupby('d').first()
    • 或者你记得indexdf['i'] = df.index这样的列,然后使用groupby
    猜你喜欢
    • 1970-01-01
    • 2020-07-21
    • 2020-12-12
    • 1970-01-01
    • 2017-03-09
    • 2020-12-09
    • 2020-02-15
    • 1970-01-01
    • 2015-11-17
    相关资源
    最近更新 更多