【问题标题】:Get last date in each month of a time series pandas获取时间序列熊猫每个月的最后日期
【发布时间】:2015-08-24 23:12:31
【问题描述】:

目前我正在使用某个函数zipline.utils.tradingcalendar.get_trading_days 生成一个 DateTimeIndex。时间序列大致是每天,但有一些差距。

我的目标是在DateTimeIndex 中获取每个月的最后日期。

.to_period('M').to_timestamp('M') 不起作用,因为它们给出了当月的最后一天,而不是每个月变量的最后一个值。

例如,如果这是我的时间序列,我想选择“2015-05-29”,而当月的最后一天是“2015-05-31”。

['2015-05-18', '2015-05-19', '2015-05-20', '2015-05-21', '2015-05-22', '2015-05-26', '2015-05-27', '2015-05-28', '2015-05-29', '2015-06-01']

【问题讨论】:

  • 抱歉df.groupby([df.index.year,df.index.month]).last()不会给你想要的东西?
  • 不,不幸的是。以我的帖子为例。
  • 我不确定 Ed 的评论为什么不起作用。您的帖子首先转换为句点,而 Ed 的评论只查看任何给定年份的任何给定月份的最后一个交易日。

标签: python pandas zipline


【解决方案1】:

试试这个,创建一个新的差异列,其中值 1 指向从一个月到下一个月的变化。

     df['diff'] = np.where(df['Date'].dt.month.diff() != 0,1,0) 

【讨论】:

    【解决方案2】:

    假设您的数据框如下所示

    original dataframe

    那么下面的代码会给你每个月的最后一天。

    df_monthly = df.reset_index().groupby([df.index.year,df.index.month],as_index=False).last().set_index('index')
    

    transformed_dataframe

    这一行代码完成了它的工作:)

    【讨论】:

      【解决方案3】:

      这是一个老问题,但这里所有现有的答案并不完美。这是我想出的解决方案(假设日期是一个排序索引),它甚至可以写在一行中,但为了便于阅读,我将其拆分:

      month1 = pd.Series(apple.index.month)
      month2 = pd.Series(apple.index.month).shift(-1)
      mask = (month1 != month2)
      apple[mask.values].head(10)
      

      这里有几点说明:

      • 转换日期时间序列需要另一个 pd.Series 实例(请参阅 here
      • 布尔掩码索引需要.values(请参阅here

      顺便说一句,当日期是工作日时,使用重采样会更容易:apple.resample('BM')

      【讨论】:

        【解决方案4】:

        也许不再需要答案了,但是在寻找同一个问题的答案时,我发现可能是一个更简单的解决方案:

        import pandas as pd 
        
        sample_dates = pd.date_range(start='2010-01-01', periods=100, freq='B')
        month_end_dates = sample_dates[sample_dates.is_month_end]
        

        【讨论】:

        • OP 明确指出“如果这是我的时间序列,我想选择 '2015-05-29' 而当月的最后一天是 '2015-05-31'。”您的解决方案将错过 2015-05-29,因为它不是月底。
        【解决方案5】:

        Condla 的回答最接近我的需要,除了因为我的时间索引延长了一年多,我需要按月和年分组,然后选择最大日期。下面是我最终得到的代码。

        # tempTradeDays is the initial DatetimeIndex
        dateRange = []  
        tempYear = None  
        dictYears = tempTradeDays.groupby(tempTradeDays.year)
        for yr in dictYears.keys():
            tempYear = pd.DatetimeIndex(dictYears[yr]).groupby(pd.DatetimeIndex(dictYears[yr]).month)
            for m in tempYear.keys():
                dateRange.append(max(tempYear[m]))
        dateRange = pd.DatetimeIndex(dateRange).order()
        

        【讨论】:

        • 喜欢它。但也许现在有一个熊猫内部解决方案......
        【解决方案6】:

        我的策略是按月分组,然后选择每个组的“最大值”:

        如果“dt”是您的 DatetimeIndex 对象:

        last_dates_of_the_month = []
        dt_month_group_dict = dt.groupby(dt.month)
        for month in dt_month_group_dict:
            last_date = max(dt_month_group_dict[month])
            last_dates_of_the_month.append(last_date)
        

        列表“last_date_of_the_month”包含数据集中每个月所有发生的最后日期。您可以使用此列表再次在 pandas 中创建 DatetimeIndex(或任何您想用它做的事情)。

        【讨论】:

          猜你喜欢
          • 2017-08-22
          • 1970-01-01
          • 2021-12-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-01
          • 2018-04-21
          相关资源
          最近更新 更多