【问题标题】:Create a dataframe for stock analysis using a datetimeindex timeseries data source使用 datetimeindex 时间序列数据源创建用于股票分析的数据框
【发布时间】:2020-06-11 01:15:54
【问题描述】:

我有一个数据源,它为我提供了以下数据框,pricehistory

+---------------------+------------+------------+------------+------------+----------+------+
|         time        |   close    |    high    |    low     |    open    |  volume  | red  |
+---------------------+------------+------------+------------+------------+----------+------+
|                     |            |            |            |            |          |      |
| 2020-01-02 10:14:00 | 321.336177 | 321.505186 | 321.286468 | 321.505186 | 311601.0 | True |
| 2020-01-02 11:16:00 | 321.430623 | 321.465419 | 321.395827 | 321.465419 | 42678.0  | True |
| 2020-01-02 11:17:00 | 321.425652 | 321.445536 | 321.375944 | 321.440565 | 39827.0  | True |
| 2020-01-02 11:33:00 | 321.137343 | 321.261614 | 321.137343 | 321.261614 | 102805.0 | True |
| 2020-01-02 12:11:00 | 321.256643 | 321.266585 | 321.241731 | 321.266585 | 25629.0  | True |
| 2020-01-02 12:12:00 | 321.246701 | 321.266585 | 321.231789 | 321.266585 | 40869.0  | True |
| 2020-01-02 13:26:00 | 321.226818 | 321.266585 | 321.226818 | 321.261614 | 44011.0  | True |
| 2020-01-03 10:18:00 | 320.839091 | 320.958392 | 320.828155 | 320.958392 | 103351.0 | True |
| 2020-01-03 10:49:00 | 320.988217 | 321.077692 | 320.988217 | 321.057809 | 84492.0  | True |
| etc...              | etc...     | etc...     | etc...     | etc...     | etc...   | etc. |
+---------------------+------------+------------+------------+------------+----------+------+

pricehistory.dtypes的输出:

close     float64
high      float64
low       float64
open      float64
volume    float64
red          bool
dtype: object

pricehistory.index.dtype 的输出: dtype('<M8[ns]')

注意:这个数据框很大,每行是 1 分钟的数据,跨越数月,所以有很多时间框需要迭代。

问题:

我想使用一些特定的标准,这些标准将成为新数据框中的列:

  1. 整个数据帧每天的高价格和时间(分钟)
  2. 白天第一次出现 4 个下降趋势分钟 open < close 及其各自的时间

到目前为止,我还不确定如何从pricehistory 中提取时间(datetimeindex 值)和高价。

对于上述 (1),我使用的是 pd.DataFrame(pricehistory.high.groupby(pd.Grouper(freq='D')).max()),这给了我:

+------------+------------+
|    time    |    high    |
+------------+------------+
|            |            |
| 2020-01-02 | 322.956677 |
| 2020-01-03 | 321.753729 |
| 2020-01-04 | NaN        |
| 2020-01-05 | NaN        |
| 2020-01-06 | 321.843204 |
| etc...     | etc...     |
+------------+------------+

但这不起作用,因为它只给我一天而不是分钟,并且使用min 作为Grouper 频率不起作用,因为它只是每个分钟的最大值,这是high

期望的结果(注:包括分钟数):

+---------------------+------------+
|    time             |    high    |
+---------------------+------------+
|                     |            |
| 2020-01-02 9:31:00  | 322.956677 |
| 2020-01-03 10:13:11 | 321.753729 |
| 2020-01-04 15:33:12 | 320.991231 |
| 2020-01-06 12:01:23 | 321.843204 |
| etc...              | etc...     |
+---------------------+------------+

对于上面的(2),我使用以下内容:

pricehistory['red'] = pricehistory['close'].lt(pricehistory['open'])

pricehistory 中创建一个新列,它会告诉我们是否连续有 4 个红色分钟。

然后,使用new_pricehistory = pricehistory.loc[pricehistory[::-1].rolling(4)['red'].sum().eq(4)],这会给出一个新的数据框,其中仅包含连续出现 4 个红色分钟的行,最好我希望只出现第一个,而不是全部。

当前输出:

+---------------------+------------+------------+------------+------------+--------+------+
|        time         |   close    |    high    |    low     |    open    | volume | red  |
+---------------------+------------+------------+------------+------------+--------+------+
|                     |            |            |            |            |        |      |
| 2020-01-02 10:14:00 | 321.336177 | 321.505186 | 321.286468 | 321.505186 | 311601 | TRUE |
| 2020-01-03 10:18:00 | 320.839091 | 320.958392 | 320.828155 | 320.958392 | 103351 | TRUE |
| 2020-01-06 10:49:00 | 320.520956 | 320.570665 | 320.501073 | 320.550781 |  71901 | TRUE |
+---------------------+------------+------------+------------+------------+--------+------+

【问题讨论】:

  • 请提供mcve并查看how-to-ask
  • @rpanai 我不知道如何使这个更清楚和具体,您需要帮助理解什么?
  • 这个问题很容易理解,但是如果您提供一些数据会很好。您甚至会增加获得答案的机会。
  • 更新了一些例子
  • 您是在寻找正好 4 个直红色还是至少 4 个?

标签: python pandas finance stock


【解决方案1】:

鉴于您没有提供数据,我创建了一些虚拟数据。根据 SO 政策,您应该针对每个问题提出不同的问题。现在我回答第一个。

生成数据

import pandas as pd
import numpy as np

times = pd.date_range(start="2020-06-01", end="2020-06-10", freq="1T")
df = pd.DataFrame({"time":times,
                  "high":np.random.randn(len(times))})

问题 1

在这里我只是寻找每天出现最大值的索引并相应地过滤df

idx = df.groupby(df["time"].dt.date)["high"].idxmax().values

df[df.index.isin(idx)]

更新:如果您有时间作为 df 中的索引,则解决方案将是

df = df.set_index("time")

idx = df.groupby(pd.Grouper(freq='D'))["high"].idxmax().values
df[df.index.isin(idx)]

问题 2

import pandas as pd
import numpy as np

# generate data
times = pd.date_range(start="2020-06-01", end="2020-06-10", freq="1T")
df = pd.DataFrame({"time":times,
                   "open":np.random.randn(len(times))})

df["open"] = np.where(df["open"]<0, -1 * df["open"], df["open"])
df["close"] = df["open"] + 0.01 *np.random.randn(len(times))
df = df.set_index("time")
df["red"] = df['close'].lt(df['open'])

# this function return the first time 
# when there are 4 consecutive red

def get_first(ts):
    idx = ts.loc[ts[::-1].rolling(4)['red'].sum().ge(4)].index
    if idx.empty:
        return pd.NaT
    else:
        return idx[0]

# get first time within group and drop nan
grp = df.groupby(pd.Grouper(freq='D'))\
        .apply(get_first).dropna()



df[df.index.isin(grp.values)]

【讨论】:

  • 数据都在上面列出了,我使用的是一个名为pricehistory的数据框,它的格式是给定的,索引是datetimeindex,它包括所有的日期/时间,不像你的那样一个整数索引和一列时间。
  • 我想指出您没有提供任何示例数据。在任何情况下,将数据框转换为您的数据框都是微不足道的,并且解决方案仍然有效。
  • 示例数据是上面给出的初始表,您的解决方案是不够的,因为它是完全不同类型的索引
  • 您提供的样本数据仅包含一行。无论如何,我更新了答案。
  • 感谢您的更新 - 我不知道为什么,但是对于 #1,我得到一个 ValueError,在使用该代码时没有特定的回溯,我不认为 idxmax()groupby上工作?
猜你喜欢
  • 2021-03-11
  • 2016-08-06
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
  • 1970-01-01
  • 1970-01-01
  • 2022-06-21
  • 2021-11-01
相关资源
最近更新 更多