我知道有一些关于这方面的帖子,但我的情况有点不同,我想在这方面得到一些帮助.

我有一个pandas pastas pastrame symbol_df,每个股票代码都有1分钟的条形图,格式如下:

id  Symbol_id                Date     Open     High      Low    Close  Volume
1          1 2023-12-13 09:15:00  4730.95  4744.00  4713.95  4696.40    2300
2          1 2023-12-13 09:16:00  4713.20  4723.70  4717.85  4702.55    1522
3          1 2023-12-13 09:17:00  4716.40  4718.55  4701.00  4701.00     909
4          1 2023-12-13 09:18:00  4700.15  4702.80  4696.70  4696.00     715
5          1 2023-12-13 09:19:00  4696.70  4709.90  4702.00  4696.10     895
...        ...                 ...      ...      ...      ...      ...     ...
108001     1 2024-03-27 13:44:00  6289.95  6291.95  6289.00  6287.55     989
108002     1 2024-03-27 13:45:00  6288.95  6290.85  6289.00  6287.75     286
108003     1 2024-03-27 13:46:00  6291.25  6293.60  6292.05  6289.10    1433
108004     1 2024-03-27 13:47:00  6295.00  6299.00  6293.20  6293.15    2702
108005     1 2024-03-27 13:48:00  6292.05  6296.55  6291.95  6291.95     983

我想计算"相对体积比率"指标,并将计算的值添加到symbol_df中,作为滚动的新列.

"相对体积比"指标计算如下:

今天的成交量与同期最后10天的平均成交量进行比较.为了得到比率值,我们简单地将"今天到目前为止的成交量"除以"同期最后10天的平均成交量".

例如...现在的wine 吧时间是13:48.

今天00:00—13:48之间的cumulativeVolumeOfToday = Volume个迷你wine 吧加起来了

过go 10天内同期(00:00—13:48)的avergeVolumeOfPreviousDaysOfSamePeriod = Average个累积量.

relativeVolumeRatio = CumulativeVolumeOfToday/AvergeVolumeOfPrevious10DaysOfSamePeriod

将此值作为新列添加到子框架中.

测试用例的样本数据下载:

import yfinance as yf #pip install yfinance
from datetime import datetime
import pandas as pd

symbol_df = yf.download(tickers="AAPL", period="7d", interval="1m")["Volume"] 
symbol_df=symbol_df.reset_index(inplace=False)
#symbol_df['Datetime'] = symbol_df['Datetime'].dt.strftime('%Y-%m-%d %H:%M')
symbol_df = symbol_df.rename(columns={'Datetime': 'Date'})
#We can only download 7 days sample data. So 5 days mean for calculations

如何在Pandas中做到这一点?

推荐答案

TL;DR

from yfinance import download

# Prepare data similar to the original
symbol_df = (
    download(tickers="AAPL", period="7d", interval="1m")
    .rename_axis(index='Date')
    .reset_index()
)

# Calculate Relative Volume Ratio
volume = symbol_df.set_index('Date')['Volume']
dts = volume.index
cum_volume = volume.groupby(dts.date, sort=False).cumsum()
prev_mean = lambda days: (
    cum_volume
    .groupby(dts.time, sort=False)
    .rolling(days, closed='left')
    .mean()
    .reset_index(0, drop=True)    # drop the level with dts.time
)
rvr = cum_volume / prev_mean(5)

# Assign the output to the initial data
symbol_df = symbol_df.join(rvr.rename('Relative volume ratio'), on='Date')

解释

根据提供的描述,您需要对聚合数据执行几个转换.首先是累积总结每天的数据.然后,在按时间分组的数据上运行一个[十]天窗口,计算平均值.最后,实际上把前者除以后者.

假设您有以下测试数据,其中"Date"是类型datetime的列:

from yfinance import download

symbol_df = (
    download(tickers="AAPL", period="7d", interval="1m")
    .rename_axis(index='Date')
    .reset_index()
)

为了计算Relative Volume Ratio个值,我们将使用"Volume"作为单独的序列,日期时间戳"Date"作为其索引:

volume = symbol_df.set_index('Date')['Volume']
dts = volume.index    # date-time stamps for convenient grouping

让我们为每天创建一个累积量序列.为此,我们将volume按日期分组(没有时间的年、月和日值),并将cumsum应用到一个组(使用sort=False以加速计算):

cum_volume = volume.groupby(dts.date, sort=False).cumsum()

为了计算给定的前几天中同一时间的累积量的平均值,我们按时间(小时和分钟,没有年、月、日值)对cum_volume进行分组,并对每组应用滚动计算,以获得窗口内的平均值.[Note that here we need the source data to be sorted by date-time stamps since only business days are taken into account and we can't use a non-fixed frequency of 102 as a 103 value.]为了计算前几天(不包括当前天数)的平均值,我们通过[closed='left'](详情见[DataFrameGroupBy.rolling docs]):

prev_mean = lambda days: (
    cum_volume
    .groupby(dts.time, sort=False)
    .rolling(days, closed='left')
    .mean()
    .reset_index(0, drop=True)
)

现在最后一次touch 窗口5天:

rvr = cum_volume / prev_mean(5)

比较

Andrei Kesely's solution相比,这一个赢得了速度(例如,在英特尔酷睿i3—2Andrei Kesely's solution上,处理那里提供的数据将需要超过1分钟,而上面的代码为300—400 ms).前10天之后的时间戳的计算结果相同.但在开始时,当之前的时间少于10天时,滚动窗口中的平均值计算就像总是有10个项目一样(缺失值设置为nan).而在Kesely的解决方案的情况下,我们只获得了available个累积体积的平均值.

Python相关问答推荐

Python中使用时区感知日期时间对象进行时间算术的Incredit

如何才能知道Python中2列表中的巧合.顺序很重要,但当1个失败时,其余的不应该失败或是0巧合

Python会扔掉未使用的表情吗?

理解Python的二分库:澄清bisect_left的使用

我从带有langchain的mongoDB中的vector serch获得一个空数组

如何使用pandasDataFrames和scipy高度优化相关性计算

PywinAuto在Windows 11上引发了Memory错误,但在Windows 10上未引发

如何在虚拟Python环境中运行Python程序?

为什么默认情况下所有Python类都是可调用的?

Polars asof在下一个可用日期加入

python—telegraph—bot send_voice发送空文件

为什么在FastAPI中创建与数据库的连接时需要使用生成器?

当单元测试失败时,是否有一个惯例会抛出许多类似的错误消息?

为什么t sns.barplot图例不显示所有值?'

如何反转一个框架中列的值?

按条件添加小计列

在我融化极点数据帧之后,我如何在不添加索引的情况下将其旋转回其原始形式?

高效生成累积式三角矩阵

Django抛出重复的键值违反唯一约束错误

大Pandas 中的群体交叉融合