Blog

课程设计与研究记录,按时间倒序排列。源码列表默认折叠,展开后可横向滚动查看。

数字时钟设计

· 51 单片机 / Proteus

设计内容

  1. 选择 51 单片机,晶振采用 12MHz。
  2. 系统可以按“秒”进行计时。
  3. 数字时钟可以显示小时(00~23)、分钟(00~59)和秒(00~59)。
  4. 可通过按键 K1 来选择设置“小时”“分钟”和“秒”。设置时可通过“加”和“减”按键(K2、K3)来调整时间;设置过程中时钟停止计时。
  5. 无键按下 3 秒钟后,自动进入时钟的计时和显示。

Proteus 仿真

Proteus 仿真电路
Proteus 仿真电路
Proteus 仿真运行结果
Proteus 仿真运行结果
程序源代码(C,238 行)
#include <reg52.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
sbit en = P3^7;
sbit rs = P3^4;
sbit rw = P3^6;

sbit k1 = P2^1;
sbit k2 = P2^2;
sbit k3 = P2^3;
sbit k0 = P2^0;

uchar key;
uchar t;

uchar time[] = {"00:00:00"};

char hour,minute,second;

void delay(uint x )
{
    uint i,j;
    for(i=0;i<x;i++) 
        for(j=0;j<120;j++); 
} 
void write_cmd(uchar cmd) 
{ 
    rs=0;
    P0=cmd;
    delay(5);
    en=1;
    delay(5);
    en=0;
    } 
void write_data(uchar dat)
    { 
        rs=1;
        P0=dat;
        delay(5);
        en=1;
        delay(5);
        en=0;
        } 
void init() { 
    uint i;
    TMOD=0x01; 
    TH0=0x4c; 
    TL0=0x01; 
    EA=1; 
    ET0=1; 
    TR0=1; 
    rw=0; 
    en=0; 
    P2=0xff; 
    hour=0; 
    minute=0; 
    second=0;
    write_cmd(0x38);
    write_cmd(0x0c); 
    write_cmd(0x06); 
    write_cmd(0x01); 
    write_cmd(0x80+0x40+3); 
    for(i=0;i<8;i++)
    { 
        write_data(time[i]); 
    } 
} 
void write_time(uchar addr,uchar dat) 
{ uchar shi,ge; 
    shi=dat/10; 
    ge=dat%10;
    write_cmd(0x80+0x40+addr);
    write_data(0x30+shi); 
    write_data(0x30+ge); 
} 
void keyscan() 
{ if(k1==0) 
    {
    delay(100); 
    if(k1==0) 
    {
        TR0=0; key++; while(k1==1); 
        if(key==1) 
        { 
            write_cmd(0x80+0x40+10); 
            write_cmd(0x0f);
            delay(1); 
        } 
        if(key==2) 
        { 
            write_cmd(0x80+0x40+7); 
            write_cmd(0x0f); 
            delay(1); 
        } 
        if(key==3) 
        {

            write_cmd(0x80+0x40+4); 
            write_cmd(0x0f); 
            delay(1); 
        } 
        if(key==4) 
        { 
            key=0;
            delay(1); 
        } 
    } 
} 
if(key!=0) 
{
    if(k0==0)
     {
        delay(5); 
        if(k0==0) 
        { 
            key=0; 
            TR0=1;
            write_cmd(0x0c); 
            delay(100);
        } 
     } 
} 
if(key!=0) 
{ 
    if(k2==0)
     {
        delay(5); 
        if(k2==0) 
        { 
            if(key==1) 
            {
                second++; 
                if(second==60) 
                { 
                    second=0;
                } 
                write_time(9,second);
    write_cmd(0x80+0x40+10);
} 

if(key==2) 
    minute++; 
    if(minute==60) 
    { 
        minute=0; 
    } 
    write_time(6,minute);
    write_cmd(0x80+0x40+7);
 } 
 if(key==3) 
 { 
    hour++; 
    if(hour==24) 
    { 
        hour=0; 
    } 
    write_time(3,hour);
    write_cmd(0x80+0x40+4); 
} 
while(k2==0);
} 
} 
if(key!=0) 
{ 
if(k3==0) 
{ 
    delay(5); 
    if(k3==0)
    { 
        if(key==1) 
        {
        second--;
        if(second==-1) 
        { 
            second=59; 
        }
         write_time(9,second); 
         write_cmd(0x80+0x40+10); 
        } 
        if(key==2) 
        {
            minute--; 
            if(minute==-1) 
            { 
                minute=59;
             } 
             write_time(6,minute); 
             write_cmd(0x80+0x40+7); 
            } 
            if(key==3) 
            { 
                hour--;
                if(hour==-1) 
                { 
                    hour=23; 
                } 
                write_time(3,hour); 
                write_cmd(0x80+0x40+4); 
            } 
            while(k3==0); 
        } 
    } 
} 
}
void main() 
{
    init(); 
    while(1) 
    { keyscan();
        if(t==20) 
        { 
            t=0; 
            second++; 
            if(second==60) 
            { 
                second=0; minute++; 
                if(minute==60)
    { 
        minute=0; 
        hour++; 
        if(hour==24) 
        { 
            hour=0;
         }
          write_time(3,hour);
         } 
         write_time(6,minute);
         }
    write_time(9,second);
        }
 }
} 
 void timer() interrupt 1 
 { 
    TH0=0x4c; 
    TL0=0x01; 
    t++; }

基于 STM32 微控制器的频率计设计

· STM32 / LCD

设计任务:利用 STM32 微控制器设计一数字频率计,采用 LCD 显示波形、频率。测量信号频率范围为 1Hz–10KHz。

频率显示
频率显示
波形显示
波形显示
程序源码 main.c(224 行)
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "exti.h"
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "lcd.h"
#include "sdram.h"
#include "key.h"
#include "timer.h"
#include "adc.h"
u32 pwm_value;
int main(void)
{
u16 adcx;
float temp;

HAL_Init(); //初始化HAL库
Stm32_Clock_Init(360,25,2,8); //设置时钟,180Mhz
delay_init(180); //初始化延时函数
uart_init(115200); //初始化USART
LED_Init(); //初始化LED
EXTI_Init(); //外部中断初始化

KEY_Init(); //初始化按键
SDRAM_Init(); //SDRAM初始化
LCD_Init(); //LCD初始化
POINT_COLOR=RED;

TIM3_PWM_Init(1000-1,9000-1);//90M/90=1M的计数频率,自动重装载为500,那么PWM频率为1M/500=2kHZ

MY_ADC_Init();
int o;
int buf[120];
for (o=0;o<360;o++) { buf[o]=0; } POINT_COLOR=RED; LCD_ShowString(10,40,260,32,32,"frquency:");
    LCD_ShowString(80,80,260,32,16,"Hz"); int i; while(1) { for (i=0;i<120;i++) { buf[i]=adcx; pwm_value=0;
    HAL_Delay(100); printf(" %d Hz \r\n ",pwm_value);


		POINT_COLOR=RED;	  
		LCD_ShowString(10,40,260,32,32," frquency:"); LCD_ShowxNum(10,80,pwm_value*10,6,16,0);
    LCD_ShowString(80,80,260,32,16,"Hz"); adcx=Get_Adc_Average(ADC_CHANNEL_5,20);//获取通道5的转换值,20次取平均
    LCD_ShowxNum(134,130,adcx,4,16,0); //显示ADCC采样后的原始值 temp=(float)adcx*(3.3/4096); //获取计算后的带小数的实际电压值,比如3.1111
    adcx=temp; //赋值整数部分给adcx变量,因为adcx为u16整形 LCD_ShowxNum(134,150,adcx,1,16,0); //显示电压值的整数部分,3.1111的话,这里就是显示3 temp-=adcx;
    //把已经显示的整数部分去掉,留下小数部分,比如3.1111-3=0.1111 temp*=1000; //小数部分乘以1000,例如:0.1111就转换为111.1,相当于保留三位小数。
    LCD_ShowxNum(150,150,temp,3,16,0X80); //显示小数部分(前面转换为了整形显示),这里显示的就是111. LCD_ShowString(142,150,200,16,16,".");
    if(i!=0) {LCD_DrawLine(10+3*i,600-20*buf[i],10+3*(i-1),600-20*buf[i-1]);} } if (i==120) i=0;LCD_Clear(WHITE); } }
    exit.c: #include "exti.h" #include "delay.h" #include "led.h" #include "key.h" void EXTI_Init(void) {
    GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟 __HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOC时钟
    __HAL_RCC_GPIOH_CLK_ENABLE(); //开启GPIOH时钟 GPIO_Initure.Pin=GPIO_PIN_0; //PA0 GPIO_Initure.Mode=GPIO_MODE_IT_RISING;
    //上升沿触发 GPIO_Initure.Pull=GPIO_PULLDOWN; HAL_GPIO_Init(GPIOA,&GPIO_Initure); GPIO_Initure.Pin=GPIO_PIN_13; //PC13
    GPIO_Initure.Mode=GPIO_MODE_IT_FALLING; //下降沿触发 GPIO_Initure.Pull=GPIO_PULLUP; HAL_GPIO_Init(GPIOC,&GPIO_Initure);
    GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3; //PH2,3 HAL_GPIO_Init(GPIOH,&GPIO_Initure); //中断线0-PA0
    HAL_NVIC_SetPriority(EXTI0_IRQn,2,0); //抢占优先级为2,子优先级为0 HAL_NVIC_EnableIRQ(EXTI0_IRQn); //使能中断线0 //中断线2-PH2
    HAL_NVIC_SetPriority(EXTI2_IRQn,2,1); //抢占优先级为2,子优先级为1 HAL_NVIC_EnableIRQ(EXTI2_IRQn); //使能中断线2 //中断线3-PH3
    HAL_NVIC_SetPriority(EXTI3_IRQn,2,2); //抢占优先级为2,子优先级为2 HAL_NVIC_EnableIRQ(EXTI3_IRQn); //使能中断线2 //中断线13-PC13
    HAL_NVIC_SetPriority(EXTI15_10_IRQn,2,3); //抢占优先级为2,子优先级为3 HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); //使能中断线13 } //中断服务函数
    void EXTI0_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);//调用中断处理公用函数 } void EXTI2_IRQHandler(void) {
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);//调用中断处理公用函数 } void EXTI3_IRQHandler(void) {
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);//调用中断处理公用函数 } void EXTI15_10_IRQHandler(void) {
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);//调用中断处理公用函数 } //中断服务程序中需要做的事情 //在HAL库中所有的外部中断服务函数都会调用此函数 //GPIO_Pin:中断引脚号
    extern int pwm_value; void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { switch(GPIO_Pin) { case GPIO_PIN_0:
    if(WK_UP==1) { pwm_value++; } break; } } key.c: #include "key.h" #include "delay.h" //按键初始化函数 void KEY_Init(void) {
    GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟 __HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOC时钟
    __HAL_RCC_GPIOH_CLK_ENABLE(); //开启GPIOH时钟 GPIO_Initure.Pin=GPIO_PIN_0; //PA0 GPIO_Initure.Mode=GPIO_MODE_INPUT; //输入
    GPIO_Initure.Pull=GPIO_PULLDOWN; //下拉 GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 HAL_GPIO_Init(GPIOA,&GPIO_Initure);
    GPIO_Initure.Pin=GPIO_PIN_13; //PC13 GPIO_Initure.Mode=GPIO_MODE_INPUT; //输入 GPIO_Initure.Pull=GPIO_PULLUP; //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速 HAL_GPIO_Init(GPIOC,&GPIO_Initure); GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3;
    //PH2,3 HAL_GPIO_Init(GPIOH,&GPIO_Initure); } //按键处理函数 //返回按键值 //mode:0,不支持连续按;1,支持连续按; //0,没有任何按键按下 //1,WKUP按下
    WK_UP //注意此函数有响应优先级,KEY0>KEY1>KEY2>WK_UP!!
    u8 KEY_Scan(u8 mode)
    {
    static u8 key_up=1; //按键松开标志
    if(mode==1)key_up=1; //支持连按
    if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))
    {
    delay_ms(10);
    key_up=0;
    if(KEY0==0) return KEY0_PRES;
    else if(KEY1==0) return KEY1_PRES;
    else if(KEY2==0) return KEY2_PRES;
    else if(WK_UP==1) return WKUP_PRES;
    }else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)key_up=1;
    return 0; //无按键按下
    }

    timer.c

    #include "timer.h"
    #include "led.h"

    TIM_HandleTypeDef TIM3_Handler; //定时器3PWM句柄
    TIM_OC_InitTypeDef TIM3_CH4Handler; //定时器3通道4句柄

    /***************************************************************************
    ****************************************************************************
    下面是PWM输出实验相关函数源码
    ****************************************************************************
    ****************************************************************************/

    //TIM3 PWM部分初始化
    //PWM输出初始化
    //arr:自动重装值
    //psc:时钟预分频数
    void TIM3_PWM_Init(u16 arr,u16 psc)
    {
    TIM3_Handler.Instance=TIM3; //定时器3
    TIM3_Handler.Init.Prescaler=psc; //定时器分频
    TIM3_Handler.Init.CounterMode=TIM_COUNTERMODE_UP;//向上计数模式
    TIM3_Handler.Init.Period=arr; //自动重装载值
    TIM3_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
    HAL_TIM_PWM_Init(&TIM3_Handler); //初始化PWM

    TIM3_CH4Handler.OCMode=TIM_OCMODE_PWM1; //模式选择PWM1
    TIM3_CH4Handler.Pulse=arr/2; //设置比较值,此值用来确定占空比,
    //默认比较值为自动重装载值的一半,即占空比为50%
    TIM3_CH4Handler.OCPolarity=TIM_OCPOLARITY_LOW; //输出比较极性为低
    HAL_TIM_PWM_ConfigChannel(&TIM3_Handler,&TIM3_CH4Handler,TIM_CHANNEL_4);//配置TIM3通道4
    HAL_TIM_PWM_Start(&TIM3_Handler,TIM_CHANNEL_4);//开启PWM通道4
    }

    //定时器底层驱动,时钟使能,引脚配置
    //此函数会被HAL_TIM_PWM_Init()调用
    //htim:定时器句柄
    void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
    {
    GPIO_InitTypeDef GPIO_Initure;

    __HAL_RCC_TIM3_CLK_ENABLE(); //使能定时器3
    __HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟

    GPIO_Initure.Pin=GPIO_PIN_1; //PB1
    GPIO_Initure.Mode=GPIO_MODE_AF_PP; //复用推完输出
    GPIO_Initure.Pull=GPIO_PULLUP; //上拉
    GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速
    GPIO_Initure.Alternate= GPIO_AF2_TIM3; //PB1复用为TIM3_CH4
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);
    }


    //设置TIM通道4的占空比
    //compare:比较值
    void TIM_SetTIM3Compare4(u32 compare)
    {
    TIM3->CCR4=compare;
    }

    //获取TIM捕获/比较寄存器值
    u32 TIM_GetTIM3Capture4(void)
    {
    return HAL_TIM_ReadCapturedValue(&TIM3_Handler,TIM_CHANNEL_4);
    }

    adc.c:

    #include "adc.h"
    #include "delay.h"
    ADC_HandleTypeDef ADC1_Handler;//ADC句柄

    //初始化ADC
    //ch: ADC_channels
    //通道值 0~16取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
    void MY_ADC_Init(void)
    {
    ADC1_Handler.Instance=ADC1;
    ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; //4分频,ADCCLK=PCLK2/4=90/4=22.5MHZ
    ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B; //12位模式
    ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT; //右对齐
    ADC1_Handler.Init.ScanConvMode=DISABLE; //非扫描模式
    ADC1_Handler.Init.EOCSelection=DISABLE; //关闭EOC中断
    ADC1_Handler.Init.ContinuousConvMode=DISABLE; //关闭连续转换
    ADC1_Handler.Init.NbrOfConversion=1; //1个转换在规则序列中 也就是只转换规则序列1
    ADC1_Handler.Init.DiscontinuousConvMode=DISABLE; //禁止不连续采样模式
    ADC1_Handler.Init.NbrOfDiscConversion=0; //不连续采样通道数为0
    ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START; //软件触发
    ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
    ADC1_Handler.Init.DMAContinuousRequests=DISABLE; //关闭DMA请求
    HAL_ADC_Init(&ADC1_Handler); //初始化
    }

    //ADC底层驱动,引脚配置,时钟使能
    //此函数会被HAL_ADC_Init()调用
    //hadc:ADC句柄
    void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
    {
    GPIO_InitTypeDef GPIO_Initure;
    __HAL_RCC_ADC1_CLK_ENABLE(); //使能ADC1时钟
    __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟

    GPIO_Initure.Pin=GPIO_PIN_5; //PA5
    GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
    GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
    HAL_GPIO_Init(GPIOA,&GPIO_Initure);
    }

    //获得ADC值
    //ch: 通道值 0~16,取值范围为:ADC_CHANNEL_0~ADC_CHANNEL_16
    //返回值:转换结果
    u16 Get_Adc(u32 ch)
    {
    ADC_ChannelConfTypeDef ADC1_ChanConf;

    ADC1_ChanConf.Channel=ch; //通道
    ADC1_ChanConf.Rank=1; //第1个序列,序列1
    ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; //采样时间
    ADC1_ChanConf.Offset=0;
    HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //通道配置

    HAL_ADC_Start(&ADC1_Handler); //开启ADC

    HAL_ADC_PollForConversion(&ADC1_Handler,10); //轮询转换

    return (u16)HAL_ADC_GetValue(&ADC1_Handler); //返回最近一次ADC1规则组的转换结果
    }
    //获取指定通道的转换值,取times次,然后平均
    //times:获取次数
    //返回值:通道ch的times次转换结果平均值
    u16 Get_Adc_Average(u32 ch,u8 times)
    {
    u32 temp_val=0;
    u8 t;
    for(t=0;t<times;t++) { temp_val+=Get_Adc(ch); delay_ms(0); } return temp_val/times; }

西安市空气质量研究

· pandas / matplotlib

基于监测点数据完成缺失值处理、相关性分析与可视化。所有 Python 代码均于 Jupyter Notebook 运行,可在上交附件的 .ipynb 文件中阅览。

散点矩阵
散点矩阵
监测数据可视化
监测数据可视化
小寨监测点
小寨监测点
分析代码(Python,390 行)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
data = pd.read_excel("附件 1. 某市监测点数据.xls")
print(data)
data = data.replace('--', np.nan)
data['可吸入颗粒物'] = data['可吸入颗粒物'].fillna(data['可吸入颗粒物
'].interpolate())
data.drop(['日期', '空气质量指数', '首要污染物', '空气质量指数级别', '空气质量
指数类别'], axis=1, inplace=True)
print(data)
data_corr = data.corr(method='pearson', min_periods=1)
data_corr.to_excel('./pearson.xls')
data_corr
scatter_matrix = pd.plotting.scatter_matrix(data,figsize=(10,6),
c = 'b',
marker = '+',
diagonal='hist',
hist_kwds={'bins':50,'edgecolor':'k'},
alpha = 0.5,
range_padding=0.1)
plt.savefig('scatter_matrix.jpg',dpi = 600,bbox_inches = 'tight')
cor_pm25=data.corr()[u'PM2.5']
print(cor_pm25)
y = data['PM2.5']
x = data['二氧化硫']
poly=np.polyfit(x,y,3)
plt.plot(x, y, 'o')
plt.plot(x, np.polyval(poly, x))
plt.xlabel("二氧化硫")
plt.ylabel("PM2.5")
plt.savefig('SO2.jpg',dpi = 600,bbox_inches = 'tight')
plt.show()
20
import math
evaluate=np.polyval(poly, x) #求拟合值
Rnew=1-math.sqrt(sum((y-evaluate)**2)/sum(y**2))
print(Rnew)
y = data['PM2.5']
x = data['二氧化氮']
poly=np.polyfit(x,y,3)
plt.plot(x, y, 'o')
plt.plot(x, np.polyval(poly, x))
plt.xlabel("二氧化氮")
plt.ylabel("PM2.5")
plt.savefig('NO2.jpg',dpi = 600,bbox_inches = 'tight')
plt.show()
evaluate=np.polyval(poly, x) #求拟合值
Rnew=1-math.sqrt(sum((y-evaluate)**2)/sum(y**2))
print(Rnew)
y = data['PM2.5']
x = data['可吸入颗粒物']
poly=np.polyfit(x,y,3)
plt.plot(x, y, 'o')
plt.plot(x, np.polyval(poly, x))
plt.xlabel("可吸入颗粒物")
plt.ylabel("PM2.5")
plt.savefig('PM10.jpg',dpi = 600,bbox_inches = 'tight')
plt.show()
evaluate=np.polyval(poly, x) #求拟合值
Rnew=1-math.sqrt(sum((y-evaluate)**2)/sum(y**2))
print(Rnew)
y = data['PM2.5']
x = data['一氧化碳']
poly=np.polyfit(x,y,3)
plt.plot(x, y, 'o')
plt.plot(x, np.polyval(poly, x))
plt.xlabel("一氧化碳")
plt.ylabel("PM2.5")
plt.savefig('CO.jpg',dpi = 600,bbox_inches = 'tight')
plt.show()
evaluate=np.polyval(poly, x) #求拟合值
Rnew=1-math.sqrt(sum((y-evaluate)**2)/sum(y**2))
print(Rnew)
y = data['PM2.5']
x = data['臭氧']
poly=np.polyfit(x,y,3)
plt.plot(x, y, 'o')
21
plt.plot(x, np.polyval(poly, x))
plt.xlabel("臭氧")
plt.ylabel("PM2.5")
plt.savefig('O3.jpg',dpi = 600,bbox_inches = 'tight')
plt.show()
evaluate=np.polyval(poly, x) #求拟合值
Rnew=1-math.sqrt(sum((y-evaluate)**2)/sum(y**2))
print(Rnew)
from sklearn import datasets,linear_model
data=data.values
regr = linear_model.LinearRegression()
X = data[:,:4]
y = data[:,5]
regr.fit(X,y)
evaluate=regr.predict(X)
#print(evaluate)
Rnew=1-math.sqrt(sum((y-evaluate)**2)/sum(y**2))
print(Rnew)
第二问:
基于 python
PM2.5 预测(以小寨为例)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False
data = pd.read_excel("附件 2.西安市监测点数据.xls",sheet_name =
None,parse_dates=["时间"])
print(data)
dfs = pd.read_excel("附件 2.西安市监测点数据.xls", sheet_name = None).values()
result = pd.concat(dfs)##将多个表 concatenate
result = result.reset_index(drop=True)##重设序列 0-最后一表的最后一行
result.from_dict(result, orient='columns', dtype=None, columns=None)##将字典类
型转换成 dataframe
result['PM2.5'] = result['PM2.5'].fillna(result['PM2.5'].mean())
result.info()
result['时间'] = pd.to_datetime(result['时间'])
result.sort_values('时间', inplace=True)##各表按时间排序
result
PM = result.pivot(index="时间", columns="点位名称", values="PM2.5")##透视表
print(PM)
PM.columns
PM[PM.columns[1]]
import plotly.express as px
22
import plotly.graph_objects as go
import plotly.io as pio
pio.templates.default = "plotly_white"
plot_template = dict(
layout=go.Layout({
"font_size": 18,
"xaxis_title_font_size": 24,
"yaxis_title_font_size": 24})
)
fig = px.line(PM, labels=dict(
date="时间", value="PM2.5",variable="点位名称"
))
fig.update_layout(
template=plot_template, legend=dict(orientation='h', y=1.02, title_text="")
)
fig.show()
data = PM
data.columns
data.info()
data.isnull().any()
data = data.dropna()
data.isnull().any()
data.columns
data.info()
data.columns
target_sensor = PM.columns[1]
features = list(data.columns.difference([target_sensor]))
forecast_lead = 1##前移 1 行,预测未来一天的数值
target = f"{target_sensor}_lead{forecast_lead}"##新列命名为**_1
data[target] = data[target_sensor].shift(-forecast_lead)##删除最后一天值
data = data.iloc[:-forecast_lead]
test_start = "2021-03-17"##设置测试集的开始时间
data_train = data.loc[:test_start].copy()#训练集
data_test = data.loc[test_start:"2021-04-17"].copy()#测试集
#
data_predict = data.loc["2021-04-17":"2021-04-27"].copy()
print("Test set fraction:", len(data_test) / len(data))#计算拆分比例
23
target_mean = data_train[target].mean()#目标站点训练集的平均值
target_stdev = data_train[target].std()#目标站点训练集的标准差
print(data_train.columns)
for c in data_train.columns:
mean = data_train[c].mean()#每个站点训练集的平均值
stdev = data_train[c].std()#每个站点的标准差
data_train[c] = (data_train[c] - mean) / stdev#每个站点减去平均值除以标准偏
差
data_test[c] = (data_test[c] - mean) / stdev

data_predict[c] = (data_predict[c]-mean) / stdev
import torch
from torch.utils.data import Dataset
class SequenceDataset(Dataset):#继承自 Dataset 类的 SequenceDataset 类
def __init__(self, dataframe, target, features, sequence_length=5):
self.features = features
self.target = target
self.sequence_length = sequence_length
self.y = torch.tensor(dataframe[target].values).float()
self.X = torch.tensor(dataframe[features].values).float()
def __len__(self):
return self.X.shape[0]
def __getitem__(self, i):
if i >= self.sequence_length - 1:
i_start = i - self.sequence_length + 1
x = self.X[i_start:(i + 1), :]#返回(i-sequence_length)到 i 行
数据
else:
padding = self.X[0].repeat(self.sequence_length - i - 1, 1)
x = self.X[0:(i + 1), :]
x = torch.cat((padding, x), 0)#填充 padding
return x, self.y[i]
i = 27
sequence_length = 4
24
train_dataset = SequenceDataset(
data_train,
target=target,
features=features,
sequence_length=sequence_length
)
X, y = train_dataset[i]
print(X)
X, y = train_dataset[i + 1]
print(X)
print(data_train[features].iloc[(i - sequence_length + 1): (i + 1)])
from torch.utils.data import DataLoader
torch.manual_seed(99)#设置随机数种子
train_loader = DataLoader(train_dataset, batch_size=3, shuffle=True)
X, y = next(iter(train_loader))
print(X.shape)
print(X)
torch.manual_seed(101)
batch_size = 4
sequence_length = 30
train_dataset = SequenceDataset(
data_train,
target=target,
features=features,
sequence_length=sequence_length
)
test_dataset = SequenceDataset(
data_test,
target=target,
features=features,
sequence_length=sequence_length
)
#
predict_dataset = SequenceDataset(
data_predict,
target=target,
25
features=features,
sequence_length=sequence_length
)
#
train_loader = DataLoader(train_dataset, batch_size=batch_size,
shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=batch_size,
shuffle=False)
X, y = next(iter(train_loader))#next()函数不断调用并返回下一个值 转换为
iterator 可迭代对象
print("Features shape:", X.shape)
print("Target shape:", y.shape)
from torch import nn
class ShallowRegressionLSTM(nn.Module):
def __init__(self, num_sensors, hidden_units):
super().__init__()
self.num_sensors = num_sensors # 特征数量
self.hidden_units = hidden_units
self.num_layers = 1
self.lstm = nn.LSTM(
input_size=num_sensors,
hidden_size=hidden_units,
batch_first=True,#(批,序列,特征)
num_layers=self.num_layers
)
self.linear = nn.Linear(in_features=self.hidden_units,
out_features=1)
def forward(self, x):#初始化 h0 和 c0 为批大小作为第二维度
batch_size = x.shape[0]
h0 = torch.zeros(self.num_layers, batch_size,
self.hidden_units).requires_grad_()
c0 = torch.zeros(self.num_layers, batch_size,
self.hidden_units).requires_grad_()
_, (hn, _) = self.lstm(x, (h0, c0))
out = self.linear(hn[0]).flatten() #线性输出层,回归任务单输出单元
# hn 的第一维是层数(在上面设为一)
26
return out
learning_rate = 0.001#5e5
num_hidden_units = 16#16
model = ShallowRegressionLSTM(num_sensors=len(features),
hidden_units=num_hidden_units)
loss_function = nn.MSELoss()#损失函数采用均方误差损失
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
def train_model(data_loader, model, loss_function, optimizer):
num_batches = len(data_loader)
total_loss = 0
model.train()
for X, y in data_loader:
output = model(X)
loss = loss_function(output, y)
optimizer.zero_grad()
loss.backward()
optimizer.step()
total_loss += loss.item()
avg_loss = total_loss / num_batches
print(f"Train loss: {avg_loss}")
def test_model(data_loader, model, loss_function):
num_batches = len(data_loader)
total_loss = 0
model.eval()
with torch.no_grad():
for X, y in data_loader:
output = model(X)
total_loss += loss_function(output, y).item()
avg_loss = total_loss / num_batches
print(f"Test loss: {avg_loss}")
print("Untrained test\n--------")
test_model(test_loader, model, loss_function)
27
print()
for ix_epoch in range(50):##epoch changed
print(f"Epoch {ix_epoch+1}\n---------")
train_model(train_loader, model, loss_function, optimizer=optimizer)
test_model(test_loader, model, loss_function)
print()
def predict(data_loader, model):
output = torch.tensor([])
model.eval()
with torch.no_grad():
for X, _ in data_loader:
y_star = model(X)
output = torch.cat((output, y_star), 0)
return output
train_eval_loader = DataLoader(train_dataset, batch_size=batch_size,
shuffle=False)
ystar_col = "Model forecast"#预测列
data_train[ystar_col] = predict(train_eval_loader, model).numpy()
data_test[ystar_col] = predict(test_loader, model).numpy()
data_out = pd.concat((data_train, data_test))[[target, ystar_col]]
for c in data_out.columns:
data_out[c] = data_out[c] * target_stdev + target_mean#还原出预测值
print(data_out)
fig = px.line(data_out, labels=dict(date="时间", value="PM2.5"))
fig.add_vline(x=test_start, line_width=4, line_dash="dash")
fig.add_annotation(xref="paper", x=0.75, yref="paper", y=0.8, text="测试集
开始", showarrow=False)
fig.update_layout(
template=plot_template, legend=dict(orientation='h', y=1.02,
title_text="")
)
fig.show()
def predict(data_loader, model):
output = torch.tensor([])
28
model.eval()
with torch.no_grad():
for X, _ in data_loader:
y_star = model(X)
output = torch.cat((output, y_star), 0)
return output
predict_loader = DataLoader(predict_dataset, batch_size=batch_size,
shuffle=False)
train_eval_loader = DataLoader(train_dataset, batch_size=batch_size,
shuffle=False)
ystar_col = "forecast"#预测列
data_train[ystar_col] = predict(train_eval_loader, model).numpy()
data_test[ystar_col] = predict(test_loader, model).numpy()
data_predict[ystar_col] = predict(predict_loader, model).numpy()
data_out = pd.concat((data_test, data_predict))[[target, ystar_col]]
for c in data_out.columns:
data_out[c] = data_out[c] * target_stdev + target_mean#还原出预测值
print(data_out)
AQI 计算
import pandas as pd
import numpy as np
iaqi = 0
def cal_linear(iaqi_lo, iaqi_hi, bp_lo, bp_hi, cp):
iaqi = (iaqi_hi - iaqi_lo) * (cp - bp_lo) / (bp_hi - bp_lo) +iaqi_lo
return iaqi
def cal_pm_iaqi(pm_val):
global iaqi
# 计算 PM2.5 的 IAQI
if 0.0 <= pm_val < 36.0: iaqi=cal_linear(0.0, 50.0, 0.0, 35.0, pm_val) elif 36.0 <=pm_val < 76.0: iaqi=cal_linear(50.0,
    100.0, 35.0, 75.0, pm_val) elif 76.0 <=pm_val < 116.0: 29 iaqi=cal_linear(100.0, 150.0, 75.0, 115.0, pm_val) elif
    116.0 <=pm_val < 151.0: iaqi=cal_linear(150.0, 200.0, 115.0, 150.0, pm_val) elif 151.0 <=pm_val < 251.0:
    iaqi=cal_linear(200.0, 300.0, 150.0, 250.0, pm_val) elif 251.0 <=pm_val < 351.0: iaqi=cal_linear(300.0, 400.0,
    250.0, 350.0, pm_val) elif 351.0 <=pm_val < 501.0: iaqi=cal_linear(400.0, 500.0, 350.0, 500.0, pm_val) else: pass
    return iaqi def cal_co_iaqi(co_val): global iaqi # 计算 co 的 IAQI if 0.0 <=co_val < 3.0: iaqi=cal_linear(0.0, 50.0,
    0.0, 2.0, co_val) elif 3.0 <=co_val < 5.0: iaqi=cal_linear(50.0, 100.0, 2.0, 4.0, co_val) elif 5.0 <=co_val < 15.0:
    iaqi=cal_linear(100.0, 150.0, 4.0, 14.0, co_val) elif 15.0 <=co_val < 25.0: iaqi=cal_linear(150.0, 200.0, 14.0,
    24.0, co_val) elif 25.0 <=co_val < 37.0: iaqi=cal_linear(200.0, 300.0, 24.0, 36.0, co_val) elif 37.0 <=co_val <
    49.0: iaqi=cal_linear(300.0, 400.0, 36.0, 48.0, co_val) elif 49.0 <=co_val < 61.0: iaqi=cal_linear(400.0, 500.0,
    48.0, 60.0, co_val) else: pass return iaqi data=pd.read_excel("附件 2.西安市监测点数据.xls") data
    data['PM2.5']=data['PM2.5'].fillna(data['PM2.5'].mean()) data['CO']=data['CO'].fillna(data['CO'].mean())
    data.columns data[['CO','PM2.5']] data['AQI_CO']=data.apply(lambda col: cal_co_iaqi(col['CO']), axis=1)
    data['AQI_PM']=data.apply(lambda col: cal_pm_iaqi(col['PM2.5']), axis=1) data.to_excel('AQI_.xls') 第四问 基于 python
    import pandas as pd 30 data=pd.read_excel("附件 3.西安地区气象数据.xls") data data.columns data['Unnamed: 1']
    se=pd.Series(data['Unnamed: 1']) countDict=dict(se.value_counts())
    proportitionDict=dict(se.value_counts(normalize=True)) print(countDict) freq=countDict freq df=pd.DataFrame([freq])
    df df.to_excel('天气.xls') import pandas as pd data=pd.read_excel("附件 3.西安地区气象数据.xls") data data.columns
    data['Unnamed: 3'] se=pd.Series(data['Unnamed: 3']) countDict=dict(se.value_counts())
    proportitionDict=dict(se.value_counts(normalize=True)) print(countDict) freq=countDict freq df=pd.DataFrame([freq])
    df df.to_excel('风向.xls')

基于 32 导 EEG 检测技术的复杂多运动实验设计与分类研究

· EEG / 分类模型

32 导 EEG 电极分布
32 导 EEG 电极分布
原始 EEG 数据
原始 EEG 数据
滤波结果
滤波结果
训练准确率曲线
训练准确率曲线
训练损失曲线
训练损失曲线
相关性热力图
相关性热力图
动画演示(2 个 GIF,合计约 36 MB,展开后加载)
分类过程动画
分类过程动画
滑动窗口切分动画
滑动窗口切分动画