电子测量技术——基于Python的测量数据误差处理程序

 

电信专业课电子测量学科使用,包括粗大误差处理、肖维纳检验法、莱特检验法、 格拉布斯检验法、累进性误差判断、周期性误差判断及给定置信概率求取置信区间部分。


  • 题目要求:

用C语言或Matlab设计测量数据误差处理的通用程序

(1)提供测试数据输入、粗大误差判别准则选择的人机界面

(2)编写程序使用说明

(3)通过实例来验证程序的正确性

  • 涉及知识

测量误差的分类及特点

随机误差的处理与估计

系统误差的处理

粗大误差的处理

测量数据处理

  • 流程图

import tkinter
import tkinter.messagebox
import math
import copy


# t分布积分表
table1_row = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 40, 60, 120]
table1_col = [50, 60, 70, 80, 90, 95, 98, 99, 999]
table1 = [[1.000, 1.376, 1.936, 3.078, 6.314, 12.706, 31.821, 63.657, 636.619],
          [0.816, 1.061, 1.386, 1.886, 2.920, 4.303,  6.965,  9.925,  31.598],
          [0.765, 0.978, 1.250, 1.638, 2.353, 3.182,  4.541,  5.841,  12.924],
          [0.741, 0.941, 1.190, 1.553, 2.132, 2.776,  3.747,  4.604,  8.610],
          [0.727, 0.920, 1.156, 1.476, 2.015, 2.571,  3.365,  4.032,  6.859],
          [0.718, 0.906, 1.134, 1.440, 1.943, 2.447,  3.143,  3.707,  5.959],
          [0.711, 0.896, 1.119, 1.415, 1.895, 2.365,  2.998,  3.499,  5.405],
          [0.706, 0.889, 1.108, 1.397, 1.860, 2.306,  2.896,  3.355,  5.041],
          [0.703, 0.883, 1.100, 1.383, 1.833, 2.262,  2.821,  3.250,  4.781],
          [0.700, 0.879, 1.093, 1.372, 1.812, 2.228,  2.764,  3.169,  4.587],
          [0.691, 0.866, 1.074, 1.341, 1.753, 2.131,  2.602,  2.947,  4.073],
          [0.687, 0.860, 1.064, 1.325, 1.725, 2.086,  2.528,  2.845,  3.850],
          [0.684, 0.856, 1.058, 1.316, 1.708, 2.06,   2.485,  2.787,  3.725],
          [0.683, 0.854, 1.055, 1.310, 1.697, 2.042,  2.457,  2.750,  3.646],
          [0.681, 0.851, 1.050, 1.303, 1.684, 2.021,  2.423,  2.704,  3.551],
          [0.679, 0.848, 1.046, 1.296, 1.671, 2.000,  2.390,  2.660,  3.460],
          [0.677, 0.845, 1.041, 1.289, 1.658, 1.980,  2.358,  2.617,  3.373]]

# 肖维纳准则表
table2 = [1.65, 1.73, 1.79, 1.86, 1.92, 1.96, 2, 2.04, 2.07, 2.1, 2.13, 2.16, 2.18, 2.2, 2.22, 2.24, 2.26, 2.28, 2.3,
          2.32, 2.33, 2.34, 2.35, 2.37, 2.38, 2.39, 2.45, 2.5, 2.58, 2.64, 2.74, 2.81, 3.02]

# 格拉布斯准则表
table3_95 = [1.15, 1.46, 1.67, 1.82, 1.94, 2.03, 2.11, 2.18, 2.23, 2.29, 2.33, 2.37, 2.41, 2.44, 2.47, 2.5, 2.53, 2.56,
             2.58, 2.60, 2.62, 2.64, 2.66]
table3_99 = [1.16, 1.49, 1.75, 1.94, 2.1, 2.22, 2.32, 2.41, 2.48, 2.55, 2.61, 2.66, 2.71, 2.75, 2.79, 2.82, 2.85, 2.88,
             2.91, 2.94, 2.96, 2.99, 3.01]


# 平均值
def average(data):
    sum_num = 0.0
    for i in data:
        sum_num += i
    return sum_num / len(data)


# 方差
def variance(data):
    aver = average(data)
    sum_num = 0
    for i in data:
        sum_num += (i - aver) ** 2
    return math.sqrt(sum_num / len(data) / (len(data) - 1))


# 累进性系统误差判断
def system_error1(data):
    aver = average(data)
    max_num = abs(data[0] - aver)
    for i in data:
        if max_num < abs(i - aver):
            max_num = abs(i - aver)
    sum1 = sum2 = 0
    for i in range(len(data) // 2 - 1):
        sum1 += abs(data[i] - aver)
    for i in range(len(data) // 2, len(data)):
        sum2 += abs(data[i] - aver)
    if abs(sum1 - sum2) >= max_num:
        return "测量中存在累进性系统误差!"
    else:
        return "测量中无累进性系统误差"


# 周期性系统误差判断
def system_error2(data):
    aver = average(data)
    num = (variance(data) * math.sqrt(len(data))) ** 2   # 标准偏差的平方
    sum_num = 0
    for i in range(len(data) - 1):
        sum_num += (data[i] - aver) * (data[i + 1] - aver)
    sum_num = abs(sum_num)
    if sum_num > num * math.sqrt(len(data) - 1):
        return "测量中存在周期性系统误差"
    else:
        return "测量中无周期性系统误差"


# 剔除坏值
def cull(data, num):
    while True:
        varian = variance(data)
        aver = average(data)
        length = len(data)
        for i in data:
            if abs(i - aver) > num * varian * math.sqrt(length):
                data.remove(i)
                break
        if len(data) == length:
            break
    return data


# 莱特检验法剔除坏值
def check1(data):
    return cull(data, 3)


# 肖维纳检验法剔除坏值
def check2(data):
    if len(data) < 5:
        print("数据少于5个!不能使用肖维纳检验法")
        return
    ch = table2[len(data) - 5]
    return cull(data, ch)


# 格拉布斯检验法剔除坏值
def check3(data, choose):
    if len(data) < 3:
        print("数据少于3个!不能使用格拉布斯检验法")
        return
    if choose == 95:
        g = table3_95[len(data) - 3]
    elif choose == 99:
        g = table3_99[len(data) - 3]
    return cull(data, g)


# 根据k和p查看置信系数
def find1(k, p):
    row = None
    col = None
    try:
        for i in range(len(table1_row)):
            if table1_row[i] == k:
                row = i
                break
        for i in range(len(table1_col)):
            if table1_col[i] == p:
                col = i
                break
        return table1[row][col]
    except TypeError:
        Tax3.insert(tkinter.END, "所查找的值不在表\n")


# 根据p求置信空间
def solve_range(data, p):
    aver = average(data)
    varian = variance(data)
    try:
        t = find1(len(data) - 1, p)
        min_num = aver - t*varian
        max_num = aver + t*varian
        return [min_num, max_num]
    except:
        return None


# 根据置信空间求p
def solve_chance(data, min_num=None):
    aver = average(data)
    varian = variance(data)
    t = (aver - min_num) / varian
    return t


# 剔除坏值的检验法选择
def select1():
    if var1.get() == -1:
        var2.set(0)


# 剔除坏值的置信概率选择
def select2():
    if var2.get() == 0:
        var1.set(-1)

def main():
    Tax3.delete(0.0, tkinter.END)
    # 获得输入数据,并转换为列表
    data_original = var.get()
    data_original = data_original.strip()
    data_original = data_original.split(',')

    for i in range(len(data_original)):
        data_original[i] = data_original[i].strip()
        data_original[i] = float(data_original[i])

    # 深拷贝原始数据
    data_new = copy.deepcopy(data_original)

    # 剔除坏值过程,choose11为用户的选择
    choose11 = var1.get()
    if choose11 == 0:
        data_new = check1(data_new)
    elif choose11 == 1:
        data_new = check2(data_new)
    elif choose11 == 2:
        data_new = check3(data_new, var2.get())
    else:
        pass

    # 求解置信区间或置信概率
    choose21 = var4.get()
    if choose21 == 0:
        p = int(var5.get())
        result_range = solve_range(data_new, p)
    elif choose21 == 1:
        num1 = float(var5.get())
        result_t = solve_chance(data_new, num1)

    # 数据的转换,都转换为字符串
    aver1 = str(round(average(data_original), 3))
    vari1 = str(round(variance(data_original), 3))
    piancha1 = str(round((variance(data_original) * math.sqrt(len(data_original))), 3))
    aver2 = str(round(average(data_new), 3))
    vari2 = str(round(variance(data_new), 3))
    piancha2 = str(round((variance(data_new) * math.sqrt(len(data_new))), 3))
    str1 = system_error1(data_new)
    str2 = system_error2(data_new)

    # 把列表转换为字符串
    for i in range(len(data_original)):
        data_original[i] = str(data_original[i])
    for i in range(len(data_new)):
        data_new[i] = str(data_new[i])
    data_original = ", ".join(data_original)
    data_new = ", ".join(data_new)

    Tax3.insert(tkinter.END, "测量数据:" + data_original + "\n")
    Tax3.insert(tkinter.END, "测量数据的均值:" + aver1 + "\n")
    Tax3.insert(tkinter.END, "测量数据的标准偏差:" + vari1 + "\n")
    Tax3.insert(tkinter.END, "测量数据的方差:" + piancha1 + "\n")
    if var1.get() != -1:
        Tax3.insert(tkinter.END, "剔除坏值后测量数据:" + data_new + "\n")
        Tax3.insert(tkinter.END, "剔除坏值后测量数据的均值:" + aver2 + "\n")
        Tax3.insert(tkinter.END, "剔除坏值后测量数据的标准偏差:" + vari2 + "\n")
        Tax3.insert(tkinter.END, "剔除坏值后测量数据的方差:" + piancha2 + "\n")

    if var4.get() == 0:
        try:
            zuo = str(round(result_range[0], 3))
            you = str(round(result_range[1], 3))
        except:
            Tax3.insert(tkinter.END, "所输入数据的自由度不在列表中,无法计算置信区间!\n")
        else:
            Tax3.insert(tkinter.END, "置信区间为:[" + zuo + ", " + you + "]\n")
    if var4.get() == 1:
        Tax3.insert(tkinter.END, "求出的t值为:" + str(round(result_t, 4)) + "\n")
    if var3.get() == 1:
        Tax3.insert(tkinter.END, str1 + "\n")
        Tax3.insert(tkinter.END, str2)


if __name__ == "__main__":
    window = tkinter.Tk()
    window.title("测量数据误差处理程序")
    window.geometry("900x700")
    window.resizable(height=False, width=False)

    # 窗口标题
    Lab1 = tkinter.Label(window, text="测量数据误差处理程序", font=("", 25))
    Lab1.place(x=250, y=0)

    # 输入数据提示及输入文本框
    var = tkinter.StringVar()
    var.set("")
    Lab2 = tkinter.Label(window, text="输入数据[数据,数据,...]:", font=("", 15))
    Lab2.place(x=3, y=60)
    Tax1 = tkinter.Entry(window, textvariable=var, width=125, font=("", 12))
    Tax1.place(x=3, y=90)

    # 误差处理的选择
    Lab3 = tkinter.Label(window, text="误差处理方式:", font=("", 15))
    Lab3.place(x=3, y=150)

    # 选择剔除的检验法(单选)
    Lab4 = tkinter.Label(window, text="剔除坏值检验法", font=("", 10))
    Lab4.place(x=30, y=190)
    var1 = tkinter.IntVar()
    var1.set(-1)
    Rbt1_1 = tkinter.Radiobutton(window, text="莱特检验法", variable=var1, value=0, command=select1)
    Rbt1_2 = tkinter.Radiobutton(window, text="肖维纳检验法", variable=var1, value=1, command=select1)
    Rbt1_3 = tkinter.Radiobutton(window, text="格布拉斯检验法", variable=var1, value=2, command=select1)
    Rbt1_4 = tkinter.Radiobutton(window, text="不进行坏值剔除", variable=var1, value=-1, command=select1)
    Rbt1_1.place(x=30, y=210)
    Rbt1_2.place(x=100, y=210)
    Rbt1_3.place(x=170, y=210)
    Rbt1_4.place(x=240, y=210)

    # 选择剔除坏值的置信概率
    Lab5 = tkinter.Label(window, text="剔除坏值置信概率", font=("", 10))
    Lab5.place(x=30, y=240)
    var2 = tkinter.IntVar()
    var2.set(0)
    Rbt2_1 = tkinter.Radiobutton(window, text="95%", variable=var2, value=95, command=select2)
    Rbt2_2 = tkinter.Radiobutton(window, text="99%", variable=var2, value=99, command=select2)
    Rbt2_3 = tkinter.Radiobutton(window, text="不进行坏值剔除", variable=var2, value=0, command=select2)
    Rbt2_1.place(x=30, y=260)
    Rbt2_2.place(x=100, y=260)
    Rbt2_3.place(x=170, y=260)

    # 选择是否进行系统误差检测
    Lab6 = tkinter.Label(window, text="是否进行系统误差检测", font=("", 10))
    Lab6.place(x=30, y=290)
    var3 = tkinter.IntVar()
    var3.set(0)
    Rbt3_1 = tkinter.Radiobutton(window, text="是", variable=var3, value=1)
    Rbt3_2 = tkinter.Radiobutton(window, text="否", variable=var3, value=0)
    Rbt3_1.place(x=30, y=310)
    Rbt3_2.place(x=100, y=310)

    # 选择求置信概率还是置信区间
    Lab7 = tkinter.Label(window, text="求置信概率还是置信区间", font=("", 10))
    Lab7.place(x=30, y=340)
    var4 = tkinter.IntVar()
    var4.set(0)
    Rbt4_1 = tkinter.Radiobutton(window, text="置信概率", variable=var4, value=1)
    Rbt4_2 = tkinter.Radiobutton(window, text="置信区间", variable=var4, value=0)
    Rbt4_1.place(x=30, y=360)
    Rbt4_2.place(x=100, y=360)

    # 输入文本框(置信概率或置信区间)
    Lab8 = tkinter.Label(window, text="请输入置信概率(求置信区间)\n(求置信概率,给出t值,自行查表)\n格式为:"
                                      "50(表示50%置信概率)", font=("", 10))
    Lab8.place(x=3, y=400)
    var5 = tkinter.StringVar()
    var5.set("")
    Tax2 = tkinter.Entry(window, textvariable=var5, width=25, font=("", 12))
    Tax2.place(x=30, y=450)

    # 输出
    Btn1 = tkinter.Button(window, text="运行", font=("", 20), command=main)
    Btn1.place(x=70, y=510)
    Tax3 = tkinter.Text(window, width=65, height=40)
    Tax3.place(x=400, y=150)

    window.mainloop()
  • 程序运行

界面板块:

数据输入板块——输入数据,以“,”分割

误差处理方式选择板块——选择检验法与置信概率等必要选项

运行板块——点击运行按钮执行程序

输出板块——输出误差处理结果

 


个人水平有限,仅限于大学学习内容,希望对各位有所帮助。

  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

YunKaiFir

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值