【发布时间】:2020-01-02 08:41:06
【问题描述】:
我有一个由 datetimeindex 索引的每日股票数据数据框。
有多个股票条目,因此存在重复的 datetimeindex 值。
我正在寻找一种方法:
- 按股票代码对数据框进行分组
- 将每个交易品种组的价格重新采样为每月价格频率数据
- 对每个交易品种组的每月价格执行 pct_change 计算
- 将其存储为原始数据框中的新列“monthly_return”。
我已经能够管理前三个操作。将结果存储在原始数据框中是我遇到麻烦的地方。
为了说明这一点,我创建了一个玩具数据集,其中包含一个“虚拟”索引 (idx) 列,我稍后在第三个代码块中使用它来帮助创建所需的输出。
import random
import pandas as pd
import numpy as np
datelist = pd.date_range(pd.datetime(2018,1,1), periods=PER).to_pydatetime().tolist() * 2
ids = [random.choice(['A', 'B']) for i in range(len(datelist))]
prices = random.sample(range(200), len(datelist))
idx = range(len(datelist))
df1 = pd.DataFrame(data=zip(idx, ids, prices), index=datelist, columns='idx label prices'.split())
print(df1.head(10))
df1
idx label prices
2018-01-01 0 B 40
2018-01-02 1 A 190
2018-01-03 2 A 159
2018-01-04 3 A 25
2018-01-05 4 A 89
2018-01-06 5 B 164
...
2018-01-31 30 A 102
2018-02-01 31 A 117
2018-02-02 32 A 120
2018-02-03 33 B 75
2018-02-04 34 B 170
...
期望的输出
idx label prices monthly_return
2018-01-01 0 B 40 0.000000
2018-01-02 1 A 190 0.000000
2018-01-03 2 A 159 0.000000
2018-01-04 3 A 25 0.000000
2018-01-05 4 A 89 0.000000
2018-01-06 5 B 164 0.000000
...
2018-01-31 30 A 102 -0.098039
2018-02-01 31 A 117 0.000000
2018-02-02 32 A 120 0.000000
...
2018-02-26 56 B 152 0.000000
2018-02-27 57 B 2 0.000000
2018-02-28 58 B 49 -0.040816
2018-03-01 59 B 188 0.000000
...
2018-01-28 89 A 88 0.000000
2018-01-29 90 A 26 0.000000
2018-01-30 91 B 128 0.000000
2018-01-31 92 A 144 -0.098039
...
2018-02-26 118 A 92 0.000000
2018-02-27 119 B 111 0.000000
2018-02-28 120 B 34 -0.040816
...
到目前为止我尝试过的是:
dfX = df1.copy(deep=True)
dfX = df1.groupby('label').resample('M')['prices'].last().pct_change(1).shift(-1)
print(dfX)
哪些输出:
label
A 2018-01-31 -0.067961
2018-02-28 -0.364583
2018-03-31 0.081967
B 2018-01-31 1.636364
2018-02-28 -0.557471
2018-03-31 NaN
这与我想做的非常接近,但是我只在月末获取 pct_change 数据,这很烦人将原始数据框 (df1) 作为新列存储。
这样的事情是行不通的:
dfX = df1.copy(deep=True)
dfX['monthly_return'] = df1.groupby('label').resample('M')['prices'].last().pct_change(1).shift(-1)
当它产生错误时:
TypeError: incompatible index of inserted column with frame index
我曾考虑将monthly_return 数据“上采样”回每日系列,但这可能最终导致上述相同的错误,因为原始数据集可能缺少日期(例如周末)。此外,重置索引以清除此错误仍然会产生问题,因为分组的 dfX 的行数/频率与原始 df1 的行数/频率不同,后者是每日频率。
我有一种预感,这可以通过使用多索引和数据框合并来完成,但是我不确定如何去做。
【问题讨论】:
-
为每个标签和输入数据提供完整几个月的数据。如果未满,至少应包括当月最后一天的数据
标签: python pandas pandas-groupby resampling