我正在使用以下代码计算每周收益:
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”。
我该如何正确处理?
答案 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