将数据分箱到相等的箱子大小并将 OLS 应用于每个箱子
Binning data into equal box sizes and apply OLS to each bin
我有一个 DataFrame df1
:
import pandas as pd
import numpy as np
import statsmodels.formula.api as sm
df1 = pd.DataFrame( np.random.randn(3000,1), index= pd.date_range('1/1/1990', periods=3000), columns = {"M"})
我想将元素分组到一个大小为 10 的盒子中,使用 OLS 拟合它们并计算 Y_t
,其中 Y_t
代表一系列直线拟合。
换句话说,我想取前 10 个值,使用 OLS 拟合它们(Y_t = b*X_t+a_0)并获得值 Y_t
这 10 个值。再次对接下来的 10 个值执行相同的操作(不是滚动 window!),依此类推。
我的做法
我遇到的第一个问题是我无法使用 DateTime
值作为预测变量来拟合元素,因此我定义了一个新的 DataFrame df_fit
,其中包含两列 A
和 B
。 A
列包含从 0 到 9 的整数,B
列包含 10 个元素为一组的 df1
的值:
def compute_yt(df,i,bs):
df_fit = pd.DataFrame({"B": np.arange(1,bs+1),\
"A": df.reset_index().loc[i*bs:((i+1)*bs-1), "M"]})
fit = sm.ols(formula = "A ~ B", data = df_fit).fit()
yt = fit.params.B*df_fit["B"] + fit.params.Intercept
return yt
其中 bs
是框大小(本例中为 10),i
是允许扫描所有值的索引。
最后,
result = [compute_yt(df1,n,l) for n in np.arange(0,round(len(df1)/l)-1)]
result =
Name: B, dtype: float64, 840 -0.249590
841 -0.249935
842 -0.250280
843 -0.250625
844 -0.250970
845 -0.251315
846 -0.251660
847 -0.252005
848 -0.252350
849 -0.252695
Name: B, dtype: float64, 850 -0.252631
851 -0.252408
... ...
其中 result
是一个应包含直线拟合值的列表。
所以,我的问题如下:
有没有办法 运行 使用 DateTime 值作为预测变量的 OLS?
我想使用列表理解来构建一个包含 y_t
值的 DataFrame(与 df1
具有相同的形状)。这与问题 (1) 有关,因为我想获得这些值的时间序列。
有没有更"pythonic"的方式来写这段代码?我切片数据框的方式似乎不太合适。
不太确定这是否是您想要做的,但我首先向数据框的每一行添加了一个组编号和一个观察编号,然后旋转它,以便每行都有 10 个观察值。
df1 = pd.DataFrame( data={'M':np.random.randn(3000)}, index= pd.date_range('1/1/1990', periods=3000))
df1['group_num'] = np.repeat(range(300), 10)
df1['obs_num'] = np.tile(range(10), 300)
df_pivot = df1.pivot(index='group_num', columns='obs_num')
print(df_pivot.head())
输出
M \
obs_num 0 1 2 3 4 5
group_num
0 -0.063775 -1.293410 0.395011 -1.224491 1.777335 -2.395643
1 -1.111679 1.668670 1.864227 -1.555251 0.959276 0.615344
2 -0.213891 -0.733493 0.175590 0.561410 1.359565 -1.341193
3 0.534735 -2.154626 -1.226191 -0.309502 1.368085 0.769155
4 -0.611289 -0.545276 -1.924381 0.383596 0.322731 0.989450
obs_num 6 7 8 9
group_num
0 -1.461194 -0.481617 -1.101098 1.102030
1 -0.120995 -1.046757 1.286074 -0.832990
2 0.322485 -0.825315 -2.277746 -0.619008
3 0.794694 0.912190 -1.006603 0.572619
4 -1.191902 1.229913 1.105221 0.899331
然后我编写了一个函数来使用 statsmodels 进行普通最小二乘 - 而不是公式类型。
import statsmodels.api as sm
def compute_yt(row):
X = sm.add_constant(np.arange(10))
fit = sm.OLS(row.values, X).fit()
yt = fit.params[1] * row.values + fit.params[0]
return yt
然后我通过 apply
在所有行上调用了这个函数。
df_pivot.apply(compute_yt, axis=1)
每组原始 10 个值输出一个预测值。
M \
obs_num 0 1 2 3 4 5
group_num
0 -0.063775 -1.293410 0.395011 -1.224491 1.777335 -2.395643
1 -1.111679 1.668670 1.864227 -1.555251 0.959276 0.615344
2 -0.213891 -0.733493 0.175590 0.561410 1.359565 -1.341193
3 0.534735 -2.154626 -1.226191 -0.309502 1.368085 0.769155
4 -0.611289 -0.545276 -1.924381 0.383596 0.322731 0.989450
obs_num 6 7 8 9
group_num
0 -1.461194 -0.481617 -1.101098 1.102030
1 -0.120995 -1.046757 1.286074 -0.832990
2 0.322485 -0.825315 -2.277746 -0.619008
3 0.794694 0.912190 -1.006603 0.572619
4 -1.191902 1.229913 1.105221 0.899331
我有一个 DataFrame df1
:
import pandas as pd
import numpy as np
import statsmodels.formula.api as sm
df1 = pd.DataFrame( np.random.randn(3000,1), index= pd.date_range('1/1/1990', periods=3000), columns = {"M"})
我想将元素分组到一个大小为 10 的盒子中,使用 OLS 拟合它们并计算 Y_t
,其中 Y_t
代表一系列直线拟合。
换句话说,我想取前 10 个值,使用 OLS 拟合它们(Y_t = b*X_t+a_0)并获得值 Y_t
这 10 个值。再次对接下来的 10 个值执行相同的操作(不是滚动 window!),依此类推。
我的做法
我遇到的第一个问题是我无法使用 DateTime
值作为预测变量来拟合元素,因此我定义了一个新的 DataFrame df_fit
,其中包含两列 A
和 B
。 A
列包含从 0 到 9 的整数,B
列包含 10 个元素为一组的 df1
的值:
def compute_yt(df,i,bs):
df_fit = pd.DataFrame({"B": np.arange(1,bs+1),\
"A": df.reset_index().loc[i*bs:((i+1)*bs-1), "M"]})
fit = sm.ols(formula = "A ~ B", data = df_fit).fit()
yt = fit.params.B*df_fit["B"] + fit.params.Intercept
return yt
其中 bs
是框大小(本例中为 10),i
是允许扫描所有值的索引。
最后,
result = [compute_yt(df1,n,l) for n in np.arange(0,round(len(df1)/l)-1)]
result =
Name: B, dtype: float64, 840 -0.249590
841 -0.249935
842 -0.250280
843 -0.250625
844 -0.250970
845 -0.251315
846 -0.251660
847 -0.252005
848 -0.252350
849 -0.252695
Name: B, dtype: float64, 850 -0.252631
851 -0.252408
... ...
其中 result
是一个应包含直线拟合值的列表。
所以,我的问题如下:
有没有办法 运行 使用 DateTime 值作为预测变量的 OLS?
我想使用列表理解来构建一个包含
y_t
值的 DataFrame(与df1
具有相同的形状)。这与问题 (1) 有关,因为我想获得这些值的时间序列。有没有更"pythonic"的方式来写这段代码?我切片数据框的方式似乎不太合适。
不太确定这是否是您想要做的,但我首先向数据框的每一行添加了一个组编号和一个观察编号,然后旋转它,以便每行都有 10 个观察值。
df1 = pd.DataFrame( data={'M':np.random.randn(3000)}, index= pd.date_range('1/1/1990', periods=3000))
df1['group_num'] = np.repeat(range(300), 10)
df1['obs_num'] = np.tile(range(10), 300)
df_pivot = df1.pivot(index='group_num', columns='obs_num')
print(df_pivot.head())
输出
M \
obs_num 0 1 2 3 4 5
group_num
0 -0.063775 -1.293410 0.395011 -1.224491 1.777335 -2.395643
1 -1.111679 1.668670 1.864227 -1.555251 0.959276 0.615344
2 -0.213891 -0.733493 0.175590 0.561410 1.359565 -1.341193
3 0.534735 -2.154626 -1.226191 -0.309502 1.368085 0.769155
4 -0.611289 -0.545276 -1.924381 0.383596 0.322731 0.989450
obs_num 6 7 8 9
group_num
0 -1.461194 -0.481617 -1.101098 1.102030
1 -0.120995 -1.046757 1.286074 -0.832990
2 0.322485 -0.825315 -2.277746 -0.619008
3 0.794694 0.912190 -1.006603 0.572619
4 -1.191902 1.229913 1.105221 0.899331
然后我编写了一个函数来使用 statsmodels 进行普通最小二乘 - 而不是公式类型。
import statsmodels.api as sm
def compute_yt(row):
X = sm.add_constant(np.arange(10))
fit = sm.OLS(row.values, X).fit()
yt = fit.params[1] * row.values + fit.params[0]
return yt
然后我通过 apply
在所有行上调用了这个函数。
df_pivot.apply(compute_yt, axis=1)
每组原始 10 个值输出一个预测值。
M \
obs_num 0 1 2 3 4 5
group_num
0 -0.063775 -1.293410 0.395011 -1.224491 1.777335 -2.395643
1 -1.111679 1.668670 1.864227 -1.555251 0.959276 0.615344
2 -0.213891 -0.733493 0.175590 0.561410 1.359565 -1.341193
3 0.534735 -2.154626 -1.226191 -0.309502 1.368085 0.769155
4 -0.611289 -0.545276 -1.924381 0.383596 0.322731 0.989450
obs_num 6 7 8 9
group_num
0 -1.461194 -0.481617 -1.101098 1.102030
1 -0.120995 -1.046757 1.286074 -0.832990
2 0.322485 -0.825315 -2.277746 -0.619008
3 0.794694 0.912190 -1.006603 0.572619
4 -1.191902 1.229913 1.105221 0.899331