python实验——移动平均和指数平滑

数据:自选或train.csv

  1. 实现移动平均;
    a) 一次移动平均,取多个n值,计算标准差;
    b) 二次移动平均,计算参数a,b,进行预测;
  2. 实现指数平滑。
    a) 一次指数平滑,取多个a值;
    b) 二次指数平滑(可选);
import pandas as pd
import numpy as np
import math

# 读取 CSV 文件
def read_cvs(file):
    content = pd.read_csv(file)
    # data = np.array(content)
    col_2 = content["Count"]
    data = np.array(col_2)
    # print(data)
    return data

# 计算 [n, m] 区间内的 count 的平均值
def avergae_n_m(data, n, m):
    sum = 0;
    for i in range(m - n):
        sum += data[i + n]
    return round(sum / (m - n))

# 一次移动平均
def one_moving_average(data, N):
    # 第一个参数是表格数据,第二个参数是 N 跨度的取值
    if N > len(data):
        return "N 的取值大于数据的数量"
    # 定义 M 来记录预测计算结果
    M = []
    for i in range(len(data) - N):
        m = avergae_n_m(data, i, i + N)
        M.append(m)
    # 预测值
    M.append(avergae_n_m(data, len(data) - N, len(data)))
    # print("预测值为:", avergae_n_m(data, len(data) - N, len(data)))
    # print(M)
    # standard_deviation(data, M, N)
    return M

# 一次移动平均 计算标准差
def standard_deviation(data, M, N):
    # 第一个参数是表格数据,第二个是预测计算的数据,第三个是 N 跨度的取值
    sum = 0
    for i in range(len(M) - 1):
        sum += (pow(M[i] - data[i + N], 2))
    # print("standard_deviation")
    S = int(math.sqrt((sum) / (len(M) - 1)))
    print("N 为",N ,"时,标准差为:", S)


# 二次移动平均
def two_moving_average(data, N):
    M1 = one_moving_average(data, N)
    M2 = one_moving_average(M1, N)
    # print(M1)
    # print(M2)
    # 计算 T
    T = 1
    # print("T:", T)
    # 计算 a
    a = 2 * M1[len(M1) - 1] - M2[len(M2) - 1]
    # 计算 b
    b = (2 / (N - 1)) * (M1[len(M1) - 1] - M2[len(M2) - 1])
    print("a:", a, "b:", b)

    # 计算 X (预测值)
    X = a + b * T
    print("N 为", N, "时,二次移动平均法预测值:", X)
    # print("two_moving_average")

# 一次指数平滑法
def one_exponential_smoothing(data, a):
    # 第一个参数是表格数据,第二个参数是 a 分析加权系数
    S = []
    # 初始值的计算 s
    if len(data) > 50:
        s = round(data[0], 1)
    elif len(data) < 3:
        s = round(data[0], 1)
    else:
        s = round((data[0] + data[1] + data[2]) / 3, 1)
    # s = round(1145.0, 1)
    S.append(s)

    # s_flag 用于记录上一个计算结果
    s_flag = s

    # print(S)
    for i in range(len(data)):
        s_now = round(a * data[i] + (1 - a) * s_flag, 1)
        s_flag = s_now
        S.append(s_now)
    # print(S)
    # print("one_exponential_smoothing")
    # print("a 为", a, "时,一次指数平滑法预测值:", S[len(S) - 1])
    return S

# 二次指数平滑法
def two_exponential_smoothing(data, a):
    M1 = one_exponential_smoothing(data, a)
    M2 = one_exponential_smoothing(M1, a)
    # print(M1)
    # print(M2)

    # 计算 a
    A = round(2 * M1[len(M1) - 1] - M2[len(M2) - 1], 1)
    # 计算 b
    b = round((a / (1 - a)) * (M1[len(M1) - 1] - M2[len(M2) - 1]), 1)
    print("a:", A, "b:", b)

    # 计算 T
    T = 1
    # print("T:", T)

    # 计算 X (预测值)
    X = A + b * T
    print("a 为", a, "时,二次指数平滑法预测值:", X)

    # print("two_exponential_smoothing")

if __name__ == '__main__':
    # 读取数据
    data = read_cvs("train.csv")
    # print(data)
    # data = [35, 38, 33, 34, 38, 40]
    # data = [533.8, 574.6, 606.9, 649.8, 705.1, 772.0, 816.4, 892.7, 963.9, 1015.1, 1102.7]
    # data = [128, 132, 140, 157, 210, 318, 325, 276, 210, 154, 137, 125]

    # data = [10, 15, 8, 20, 10, 16, 18, 20, 22, 24, 20, 26, 27, 29, 29]
    # data = [5.25, 3.46, 2.67, 3.25, 4.70, 5.46, 5.18, 2.14, 4.23, 4.62, 1.57, 4.69]
    # data = [1344, 1650, 1951, 1641, 1515, 1982, 2519, 2818, 2937, 3142, 3093, 3500, 3497, 3944, 4416]

    # 一次移动平均法
    # for i in range(2,20):
    #     one_moving_average(data, i)

    # one_moving_average(data, 4)

    # 二次移动平均法
    for i in range(2,7):
        two_moving_average(data, i)

    # 一次指数平滑法
    # for i in range(1, 10):
    #     a = i / 10
    #     one_exponential_smoothing(data, a)

    # 二次指数平滑法
    # for i in range(1, 10):
    #     a = i / 10
    #     two_exponential_smoothing(data, a)
        # print(a)

一次移动平均法:
在这里插入图片描述
二次移动平均法:
在这里插入图片描述

一次指数平滑法:
在这里插入图片描述

二次指数平滑法:
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值