Pandas计算历史均值

在用Python进行时间序列分析时,我们可能经常需要计算历史的一些特征。一般会使用rolling()函数,这里介绍一下计算包括当前行的历史特征和不包括当前行的历史特征

1. 包括当前行

这里先简单介绍一下rolling()函数
pandas.DataFrame.rolling官方文档

DataFrame.rolling(window, min_periods=None, center=False, win_type=None, on=None, axis=0, closed=None, step=None, method=‘single’)

常用参数解释:

  • window: 时间窗大小,一般为整数,表示向前观测n个数据
  • min_periods: 最小需要有值的观测点的数量
  • center: 是否使用当前行作为窗口的中间行
  • on: 对于多列的DataFrame, 用on指定使用哪列
  • axis: 0→行,1→列

举个例子

data = {'A': ['a','a','a','a','a','a','b','b','b','b','b'],
       'B': [1,4,5,7,5,9,6,1,4,5,6]}
df = pd.DataFrame(data)

在这里插入图片描述

获取每组当前行和上面两行(一共3行)的均值

# 这里可以对比一下前3个常用参数的区别
# mean()可以改成自己需要的公式
df['C'] = df.groupby(['A'])['B'].apply(lambda x: x.rolling(3).mean())
# df['C'] = df.groupby(['A'],as_index=False)['B'].rolling(3).mean()[['B']]
df['D'] = df.groupby(['A'])['B'].apply(lambda x: x.rolling(3,min_periods=1).mean())
df['E'] = df.groupby(['A'])['B'].apply(lambda x: x.rolling(3, center=True).mean())

在这里插入图片描述


2. 不包括当前行

但在使用rolling()获取前几行的数值进行计算时,都会包括当前行。如果我们的计算不想包括当前行的数值,我们还需要额外使用bfill()shift()进行计算

bfill()用于向后填充数值,相当于fillna(method='bfill')
pandas.DataFrame.bfill官方文档

shift()用于上下/左右移动数据
pandas.DataFrame.shift官方文档

继续用刚才的例子

# 向下移动
df['C'] = df.groupby(['A'])['B'].apply(lambda x: x.shift(1))
# 向上移动
df['D'] = df.groupby(['A'])['B'].apply(lambda x: x.shift(-1))

在这里插入图片描述

如果我们想计算不包括当前行的前面几行数据的均值,我们可以先计算当前行的下一行开始rolling()的均值,然后再往上移一行

# 先计算后面一行的rolling(3).mean()
df['C'] = df.groupby(['A'])['B'].apply(lambda x: x.rolling(3,1).mean().shift())
# 向上一行填充
df['final'] = df.groupby(['A'])['B'].apply(lambda x: x.rolling(3,1).mean().shift().bfill())

在这里插入图片描述

final那列就是我们计算不包括当前行的前三行的平均值


参考来源:
pandas groupby shift rank rolling 等用法详解
Pandas -计算组的滚动平均值,不包括当前行

均值策略是一种基于移动平均线的简单交易策略,使用两条移动平均线来发出交易信号。当较短期的均线穿过较长期的均线向上突破时,产生买入信号;当较短期的均线穿过较长期的均线向下突破时,产生卖出信号。 以下是使用Python实现双均值策略的代码: ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt # 读取数据 df = pd.read_csv('data.csv') # 计算短期均线和长期均线 short_ma = df['Close'].rolling(window=5).mean() long_ma = df['Close'].rolling(window=10).mean() # 交易信号 signals = pd.Series(0, index=df.index) signals[5:] = np.where(short_ma[5:] > long_ma[5:], 1, 0) signals[5:] = np.where(short_ma[5:] < long_ma[5:], -1, signals[5:]) # 持仓情况 positions = signals.diff() # 绘制图表 fig = plt.figure() ax1 = fig.add_subplot(111, ylabel='Price') df['Close'].plot(ax=ax1, color='r', lw=2.) short_ma.plot(ax=ax1, color='g', lw=2.) long_ma.plot(ax=ax1, color='b', lw=2.) plt.legend(['Price', 'Short ma', 'Long ma'], loc='upper left') # 画出买卖信号 ax1.plot(signals[signals == 1].index, df['Close'][signals == 1], '^', markersize=10, color='m') ax1.plot(signals[signals == -1].index, df['Close'][signals == -1], 'v', markersize=10, color='k') plt.show() ``` 在这个例子中,我们使用了一个名为"data.csv"的数据文件。你可以将其替换为具体的股票或其他资产的历史价格数据。 该代码将股票价格和短期/长期移动平均线绘制在同一图表中,并标记出交易信号(买入信号为向上箭头,卖出信号为向下箭头)。 请注意,这是一个非常简单的交易策略,仅供学习和演示用途。实际上,双均值策略可能无法在真实的市场环境中获得可靠的收益。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值