数字时钟设计
Published on: January 10, 2024
1.设计内容
(1)选择51单片机,晶振采用12MHz。
(2)系统可以按“秒”进行计时。
(3)数字时钟可以显示小时(00~23)、分钟(00~59)和秒(00~59)。
(4)可通过按键K1来选择设置“小时”、“分钟”和“秒”。设置时可通过“加”和“减”按键(K2、K3)来调整时间;设置过程中时钟停止计时。
(5)无键按下3秒钟后,自动进入时钟的计时和显示。
proteus 仿真图如下:
程序源代码:
#include
#include
#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
基于STM32微控制器的频率计设计
Published on: January 15, 2024
设计任务:利用STM32微控制器设计一数字频率计,采用LCD显示波形、频率。测量信号频率范围为1Hz-10KHz。
程序源码
main.c
#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
西安市空气质量研究
Published on: January 15, 2024
第一问:
基于 python
(所有 python 代码均于 Jupyter notebook 运行,可于上交附件中.ipynb 文件中阅览)
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')