计算每周收益时发生Pct_change收益错误

时间:2018-12-21 22:16:59

标签: python pandas numpy

我正在使用以下代码计算每周收益:

import pandas as pd

import numpy as np

df = pd.DataFrame({'price': np.arange(100)}).set_index(pd.date_range('2015', periods = 100, freq = 'B')) 

df.price.pct_change(periods = 1, freq = 'W')

我收到了以下错误消息:

  

ValueError:无法从重复的轴重新索引

我尝试将频率更改为其他选项,例如,月份为“ M”,年度为“ A”,这些都不起作用,似乎唯一有价值的工作是“ B”。

我该如何正确处理?

1 个答案:

答案 0 :(得分:1)

df.resample("W").ffill().pct_change(periods=1)

根据此链接https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.pct_change.html

  

期间:int,默认为1

     

为形成百分比变化而改变的时期。

     

freq:DateOffset,timedelta或偏移别名字符串,可选

     

在时间序列API中使用的增量(例如“ M”或BDay())。

如果您想知道哪些频率值可以,请在此处查看:https://pandas.pydata.org/pandas-docs/stable/timeseries.html#dateoffset-objects

编辑:我再次阅读了您的问题,并且我注意到“每周收益”是完成任务的关键。因此,填充将不是您正在寻找的一种解决方案。您可能更希望计算每个企业每周工作6天的总金额,因此“总和”应该更合适,所以在这里:

1)df.resample("W").sum():

            price
2015-01-04      1
2015-01-11     20
2015-01-18     45
2015-01-25     70
2015-02-01     95
2015-02-08    120
2015-02-15    145
2015-02-22    170
2015-03-01    195
2015-03-08    220
2015-03-15    245
2015-03-22    270
2015-03-29    295
2015-04-05    320
2015-04-12    345
2015-04-19    370
2015-04-26    395
2015-05-03    420
2015-05-10    445
2015-05-17    470
2015-05-24    294

2)然后应用pct_change(period=1),我们想强调每行之间的变化(请注意,periods=1这里是多余的:我们只能使用pct_change()):

                price
2015-01-04        NaN
2015-01-11  19.000000
2015-01-18   1.250000
2015-01-25   0.555556
2015-02-01   0.357143
2015-02-08   0.263158
2015-02-15   0.208333
2015-02-22   0.172414
2015-03-01   0.147059
2015-03-08   0.128205
2015-03-15   0.113636
2015-03-22   0.102041
2015-03-29   0.092593
2015-04-05   0.084746
2015-04-12   0.078125
2015-04-19   0.072464
2015-04-26   0.067568
2015-05-03   0.063291
2015-05-10   0.059524
2015-05-17   0.056180
2015-05-24  -0.374468

如果要突出显示两行,三行,...,n行之间的pct更改,则需要自定义periods关键字:

df.resample("W").sum().pct_change(periods=2)

2015-01-04        NaN
2015-01-11        NaN
2015-01-18  44.000000
2015-01-25   2.500000
2015-02-01   1.111111
2015-02-08   0.714286
2015-02-15   0.526316
2015-02-22   0.416667
2015-03-01   0.344828
2015-03-08   0.294118
2015-03-15   0.256410
2015-03-22   0.227273
2015-03-29   0.204082
2015-04-05   0.185185
2015-04-12   0.169492
2015-04-19   0.156250
2015-04-26   0.144928
2015-05-03   0.135135
2015-05-10   0.126582
2015-05-17   0.119048
2015-05-24  -0.339326
当您要考虑总周趋势时,

Resample()。sum()很重要。但也许您想强调其他增长趋势。因此,在这里我们使用ffill()来用先前的值填充“空”行。

1)df.resample(“ W”)。ffill()

            price
2015-01-04      1
2015-01-11      6
2015-01-18     11
2015-01-25     16
2015-02-01     21
2015-02-08     26
2015-02-15     31
2015-02-22     36
2015-03-01     41
2015-03-08     46
2015-03-15     51
2015-03-22     56
2015-03-29     61
2015-04-05     66
2015-04-12     71
2015-04-19     76
2015-04-26     81
2015-05-03     86
2015-05-10     91
2015-05-17     96
2015-05-24     99

您可能会注意到,这些行代表我们在“ df”中未使用的星期几。它们主要采用行日期之前的第一天的值: 从2015-01-02的2015-01-04 从2015年1月1日至2015年1月11日,等等。

2)df.resample("W").ffill().pct_change()

               price
2015-01-04       NaN
2015-01-11  5.000000
2015-01-18  0.833333
2015-01-25  0.454545
2015-02-01  0.312500
2015-02-08  0.238095
2015-02-15  0.192308
2015-02-22  0.161290
2015-03-01  0.138889
2015-03-08  0.121951
2015-03-15  0.108696
2015-03-22  0.098039
2015-03-29  0.089286
2015-04-05  0.081967
2015-04-12  0.075758
2015-04-19  0.070423
2015-04-26  0.065789
2015-05-03  0.061728
2015-05-10  0.058140
2015-05-17  0.054945
2015-05-24  0.031250

考虑到上述情况,我们可以使用其他频率,例如每月一次:

df.resample("M").sum().pct_change()

               price
2015-01-31       NaN
2015-02-28  1.727273
2015-03-31  0.833333
2015-04-30  0.419048
2015-05-31 -0.209884