【发布时间】:2016-07-01 15:54:36
【问题描述】:
我有一个值的数据框:
df = pd.DataFrame(np.random.uniform(0,1,(500,2)), columns = ['a', 'b'])
>>> print df
a b
1 0.277438 0.042671
.. ... ...
499 0.570952 0.865869
[500 rows x 2 columns]
我想通过用它们的百分位数替换这些值来转换这一点,其中百分位数将取代之前行中所有值的分布。即,如果您执行 df.T.unstack(),它将是一个纯扩展样本。如果您将索引视为 DatetimeIndex,这可能会更直观,并且我要求在整个横截面历史中采用扩展百分位数。
所以目标就是这个人:
a b
0 99 99
.. .. ..
499 58 84
(理想情况下我想在 and 之前的所有行中的所有值集合上分配一个值,包括该行,所以不完全是扩展百分位数;但如果我们不能得到,那也没关系。)
我有一个真的丑陋的方法来做这件事,我转置和取消堆叠数据帧,生成一个百分位掩码,并使用 for 循环将该掩码覆盖在数据帧上以获取百分位数:
percentile_boundaries_over_time = pd.DataFrame({integer:
pd.expanding_quantile(df.T.unstack(), integer/100.0)
for integer in range(0,101,1)})
percentile_mask = pd.Series(index = df.unstack().unstack().unstack().index)
for integer in range(0,100,1):
percentile_mask[(df.unstack().unstack().unstack() >= percentile_boundaries_over_time[integer]) &
(df.unstack().unstack().unstack() <= percentile_boundaries_over_time[integer+1])] = integer
我一直在尝试使用 scipy.stats.percentileofscore() 和 pd.expanding_apply() 来加快工作速度,但它没有给出正确的输出,我正在疯狂地试图找出原因。这是我一直在玩的:
perc = pd.expanding_apply(df, lambda x: stats.percentileofscore(x, x[-1], kind='weak'))
有没有人对为什么这会给出不正确的输出有任何想法?或者更快的方法来完成整个练习?非常感谢任何和所有帮助!
【问题讨论】:
-
是什么让您认为您的扩展应用程序给出了错误的结果?乍一看,它看起来不错(在每一列中,它似乎不允许跨行组合)。也许在生成数据之前打一个
np.random.seed()电话,以便其他人可以根据相同的数据检查结果?
标签: python pandas scipy percentile