显示自某物翻倍以来已经过了多长时间

Display how long it has been since something doubled

我读到一个有趣的统计数据,自去年以来,股市在最短的休息时间内上涨了 100%(即翻了一番)——我期待 test/replicate 这一说法。

以下数据来自 FRED(美联储数据存放处),是 WILL5000 指数的数据,该指数可追溯到 1970 年,而标准普尔指数仅到 2011 年。

| DATE                |   WILL5000 |    50%   |
| 1970-12-31 00:00:00 |       1    |    0.5   |
| 1971-01-01 00:00:00 |     nan    |    nan   |
| 1971-01-04 00:00:00 |     nan    |    nan   |
| 1971-01-05 00:00:00 |     nan    |    nan   |
| 1971-01-06 00:00:00 |     nan    |    nan   |
|         ...         |     ...    |    ...   |
| 2021-07-21 00:00:00 |   216.54   |  108.27  |
| 2021-07-22 00:00:00 |   216.68   |  108.34  |
| 2021-07-23 00:00:00 |   218.84   |  109.42  |
| 2021-07-26 00:00:00 |   219.32   |  109.66  |
| 2021-07-27 00:00:00 |   218.07   |  109.035 |

我想到的一种方法是添加一个列,其中包含 WILL5000 索引值的一半,然后使用代码搜索低于该水平的值(这将是 100% 移动),并记录它有多少天从那以后。

我似乎无法在任何地方找到如何做到这一点 - 并且很想听听任何其他实现它的方法。

这个问题在你的系列中有 O(n<sup>2</sup>) 个步骤 n 个点。

对于序列中的 i<sup>th</sup> 点,您需要检查 w<sub>j</sub> >= 2w<sub>i</sub> 所有 j > i。在第一个 j (如果有的话)满足每种情况下的要求。换句话说,将一个日期固定为基线,然后在所有未来日期中寻找翻倍的条件;对所有可能的基准日期执行此操作。

在 Pandas 中,这意味着您必须 (i) 将数据帧与其自身交叉合并并将其过滤到“上三角”(即 j > i)部分,( ii) 在 i.

上找到每组第一次加倍的时间

这是完成工作的 Python+Pandas 代码:

import numpy as np
import pandas as pd

# load your data --> construct synthetic df for this example
np.random.seed(52)
date_axis = pd.date_range('1970-01-01', '2021-01-01', freq='M')
n = len(date_axis)
raw_df = pd.DataFrame(data={'date': date_axis, 'ticker_value': 300.0 * np.random.rand(n)})

# create n^2 df
df = pd.merge(raw_df, raw_df, how='cross').sort_values(by=['date_x', 'date_y'])

# restrict to upper triangle
df = df.loc[df.date_y > df.date_x, :]

# add a column to check if doubling condition is met
df['is_at_least_double'] = (df.ticker_value_y >= 2.0 * df.ticker_value_x)

# throw away values that don't meet the condition
df = df.loc[df.is_at_least_double, :].drop(columns=['is_at_least_double'])

# pick up the first value that satisfies the condition -- this is why we did the sort
df = df.groupby('date_x').first().reset_index()

# find intervals
df['interval'] = df.date_y - df.date_x

# find the smallest interval; tie-breaker is the one with the earliest base date
df.sort_values(by=['interval', 'date_x'], inplace=True)
solution = df.iloc[0]

print(solution)

注释解释了代码中的步骤。我建议 运行 在控制台中逐行检查它并检查中间结果以了解发生了什么。