假设我有一个pandas表,其中一列是股票代码,另一列是日期,我希望,对于每个日期,重新调整返回以遵循统一分布。现在,sklearn.preprocessing
对此有一个非常好的quantile_transform
函数,但我似乎无法将其变为大熊猫tranform
或apply
功能,
强制性的例子:
date ticker volume percent_change
2018-01-01 A 10000 0.01
2018-01-01 AA 15000 0.002
2018-01-01 AAPL 20000 -0.01
2018-01-01 FB 10000 0.05
2018-01-02 A 10000 -0.01
2018-01-02 AA 15000 0.03
2018-01-02 AAPL 20000 -0.02
2018-01-02 FB 10000 -0.01
如果我想将每日回报标准化为zscore,则以下工作正常:
zscore = lambda x: (x - x.mean()) / x.std()
df['zscore'] = tsdf.groupby('date')['percent_change'].transform(zscore)
但quantile_transform
似乎更顽固。
答案 0 :(得分:1)
试试这个:
In [216]: for n,g in df.groupby('date'):
...: df.loc[df['date']==n, 'zscore'] = \
quantile_transform(df.loc[df['date']==n, ['percent_change']]).ravel()
In [217]: df
Out[217]:
date ticker volume percent_change zscore
0 2018-01-01 A 10000 0.010 6.666667e-01
1 2018-01-01 AA 15000 0.002 3.333333e-01
2 2018-01-01 AAPL 20000 -0.010 1.000000e-07
3 2018-01-01 FB 10000 0.050 9.999999e-01
4 2018-01-02 A 10000 -0.010 5.005005e-01
5 2018-01-02 AA 15000 0.030 9.999999e-01
6 2018-01-02 AAPL 20000 -0.020 1.000000e-07
7 2018-01-02 FB 10000 -0.010 5.235235e-01
quantile_transform()
期望2D数组作为输入 - 这就是我们需要方括号的原因:
df.loc[df['date']==n, ['percent_change']]
# ^ ^
它返回一个2D矩阵作为结果,所以我们需要展平(.ravel()
)它......
答案 1 :(得分:0)
循环很慢,我有更好的方法:
from sklearn.preprocessing import QuantileTransformer
qt = QuantileTransformer(n_quantiles=100, random_state=0)
lam = lambda x: qt.fit_transform(x.values.reshape(-1, 1)).ravel()
df['result'] = df.groupby('date')['percent_change'].transform(lam)