【问题标题】:Changing frequency of pandas Period and PeriodIndex熊猫 Period 和 PeriodIndex 的变化频率
【发布时间】:2018-03-04 20:42:52
【问题描述】:

我正在将一些具有年度报告信息的股票数据导入到 pandas DataFrame 中。但是年报的结束日期是奇数月(一月底),而不是年末。

years = ['2017-01-31', '2016-01-31', '2015-01-31']
df = pd.DataFrame(data = years, columns = ['years'])

df
Out[357]: 
        years
0  2017-01-31
1  2016-01-31
2  2015-01-31

当我尝试添加一个显示报告数据有效时间段的 PeriodIndex 时,它默认为在 12 月结束,而不是从日期字符串中推断出来

df.index = pd.PeriodIndex(df['years'], freq ='A')

df.index

Out[367]: PeriodIndex(['2017', '2016', '2015'], dtype='period[A-DEC]', 
name='years', freq='A-DEC')

请注意,频率应为“A-JAN”。

我认为这意味着不能从 PeriodIndex 和我给出的结束日期字符串中推断出结束日期。

我可以使用 asfreq 方法更改它,并使用“A-JAN”作为频率字符串来锚定偏移量anchored offsets。但是,这会更改 PeriodIndex 中的所有单个期间,而不是单独更改,因为年份的年度报告可能有不同的报告结束日期(如果公司更改了报告期间)。

有没有办法解释每个日期字符串并为我的 pandas 框架中的每一行正确设置每个句点?

我的最终目标是设置一个周期列或索引,其频率为“年度”,但周期结束日期设置为年份列相应行的日期。

** 进一步扩展这个问题。考虑到我有许多股票,每只股票都有 3-4 年的年度财务数据,而且它们的年度报告频率(或季度报告)的开始和结束日期各不相同。

Out[14]: 
        years tickers
0  2017-01-31      PG
1  2016-01-31      PG
2  2015-01-31      PG
3  2017-05-31       T
4  2016-05-31       T
5  2015-05-31       T

我想要得到的是一列,其中包含适当的 Period 对象,这些对象配置有适当的结束日期(来自年份列),并且都具有年度频率。我考虑过尝试迭代这些年并使用 apply.map 或 lambda 函数和 pd.Period 函数。可能是 PeriodIndex 不能存在其中具有不同结束日期的不同 Period 对象。像

for row in df.years:
    s.append(pd.Period(row, freq='A")
df['period']= s

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    @KRkirov 让我开始思考。看来 Period 构造函数不够聪明,无法通过读取日期字符串来设置频率的结束日期。我能够通过从报告期的结束日期建立一个锚字符串来获得正确的频率结束日期,如下所示:

    # return a month in 3 letter abbreviation format (eg. "JAN")
    df['offset'] = df['years'].dt.strftime('%b').str.upper()
    
    # now build up an anchor offset string (eg. "A-JAN" )
    # for quarterly report (eg. "Q-JAN") for q report ending January for year
    df['offset_strings'] = "A" + '-' + df.offset
    

    锚字符串记录在 pandas 文档 here

    然后遍历DataFrame的行来构造每个Period并放入一个列表中,然后将Period对象的列表(被强制到一个PeriodIndex)添加到一个列中。

    ps = []
    for i, r in df.iterrows():
         p = pd.Period(r['years'], freq = r['offset_strings']))
         ps.append(p)
    df['period'] = ps
    

    这将返回一个正确的 PeriodIndex 并正确设置 Period 对象:

    df['period']
    Out[40]: 
    0   2017
    1   2016
    2   2015
    Name: period, dtype: object
    
    df['period'][0]
    Out[41]: Period('2017', 'A-JAN')
    
    df.index = df.period
    
    df.index
    Out[43]: PeriodIndex(['2017', '2016', '2015'], dtype='period[A-JAN]', 
    name='period', freq='A-JAN')
    

    不漂亮,但我找不到其他方法。

    【讨论】:

      猜你喜欢
      • 2018-07-24
      • 2014-02-05
      • 2020-08-25
      • 2017-05-28
      • 2019-04-01
      • 2013-05-09
      • 1970-01-01
      • 2016-11-14
      • 2019-05-26
      相关资源
      最近更新 更多