【问题标题】:Python percentile of recent value vs window of previous values最近值的 Python 百分位数与先前值的窗口
【发布时间】:2018-12-06 19:34:31
【问题描述】:

抱歉,我是一个想要从 R 过渡的菜鸟!

可重现的数据示例;

df = pd.DataFrame(1.26 + np.random.rand(size)/100.0,
                  index=pd.date_range('20160101 09:00:00',
                                      periods=size,
                                      freq='60s'),
                  columns=['ATR20'])

我想在 ATR20 列中取一个值,并根据 ATR20 列的前 n 个值的滚动窗口计算其当前百分位数。

据我所知:

for n in range(1,len(df)):
print(sum(df.ATR20[n:n+20] > df.ATR20))

这给出了以下错误:

ValueError: Can only compare identically-labeled Series objects

我确信有一种更简单的方法可以使用更简洁的语法来做到这一点,但我的搜索没有找到足够接近的东西。

谢谢。

【问题讨论】:

  • 首先,看看你想要总结什么:如果你让df.ATR20[n:n+20]df.ATR20 工作正常,这将是一系列 20 个布尔值,告诉你 @ 中的每个值987654326@是否大于ATR20中的对应值。因此,将这些布尔值相加只会计算更大的数字(因为 TrueFalse 以及添加为数字时的 1 和 0)。这就是你想要的第一步吗?如果是这样,可以修复它……但如果不是,请解释您在第一步中实际尝试做的事情。

标签: python pandas numpy percentile


【解决方案1】:

我认为这会得到你想要的。我使用了您的示例,其中数据框中只有 10 个元素和一个包含 3 个元素的滚动窗口,因此粘贴在这里时会更短。

size = 10
df = pd.DataFrame(1.26 + np.random.rand(size)/100.0,
                  index=pd.date_range('20160101 09:00:00',
                                      periods=size,
                                      freq='60s'),
                  columns=['ATR20'])

#                         ATR20
# 2016-01-01 09:00:00  1.262522
# 2016-01-01 09:01:00  1.265116
# 2016-01-01 09:02:00  1.265051
# 2016-01-01 09:03:00  1.261109
# 2016-01-01 09:04:00  1.262699
# 2016-01-01 09:05:00  1.266710
# 2016-01-01 09:06:00  1.260186
# 2016-01-01 09:07:00  1.268001
# 2016-01-01 09:08:00  1.263227
# 2016-01-01 09:09:00  1.261331

您可以使用df.rollingapply 将函数应用于滚动窗口。我认为我在这里使用的计算或多或少是您正在寻找的:

window = 3
df.rolling(window).apply(lambda x: sum([x[-1] > i for i in x]) / (window - 1))

#                         ATR20
# 2016-01-01 09:00:00       NaN
# 2016-01-01 09:01:00       NaN
# 2016-01-01 09:02:00  0.263665
# 2016-01-01 09:03:00  0.000000
# 2016-01-01 09:04:00  0.263932
# 2016-01-01 09:05:00  0.527632
# 2016-01-01 09:06:00  0.000000
# 2016-01-01 09:07:00  0.527024
# 2016-01-01 09:08:00  0.263754
# 2016-01-01 09:09:00  0.000000

【讨论】:

  • 你能解释一下上面的代码吗?据我了解,i 是 ATR20 的当前值,x 是滚动函数中定义的尺寸系列?上面看起来是对的,但是要将我们的排名计算为百分位数,我认为我们应该除以窗口大小 -1 而不是 x.sum。
  • 我在等式上可能是错误的,但它所做的是取x 的每个元素(我们指定的任何大小的滚动窗口),如果它小于最后一个元素,则将其相加x,即我们窗口的结尾。然后它除以x 中所有元素的总和,因此您得到了x[-1] 所代表的百分位数。如果你只是将小于x 的所有元素相加并除以窗口的长度,那么我认为这将是x[-1]rank 的百分位数,如果那就是你想要的。告诉我,我可以更新它。
  • 是的,这就是我要找的。使用带有轻微 mod 的代码可以让我得到想要的结果。 df.rolling(3).apply(lambda x: sum([x[-1] > i for i in x]) / 2)
  • 更新了我的答案!您确定要除以2吗?我想你会想除以你的窗口大小。或者window - 1
  • Window -1,因为窗口包含当前选择。
猜你喜欢
  • 2020-07-16
  • 1970-01-01
  • 2023-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多