Groupby quantile_transform

时间:2018-03-12 16:19:10

标签: python pandas

假设我有一个pandas表,其中一列是股票代码,另一列是日期,我希望,对于每个日期,重新调整返回以遵循统一分布。现在,sklearn.preprocessing对此有一个非常好的quantile_transform函数,但我似乎无法将其变为大熊猫tranformapply功能,

强制性的例子:

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似乎更顽固。

2 个答案:

答案 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)