%
% Шаблон для НИР версия 2021
%
\documentclass[a4paper,12pt]{article}
\usepackage{vkriate}
% Настройки для окружений с подчеркиваниями для подписей и пр.
\setFRMfontencoding{T2A}
\setFRMdfontencoding{T2A}
% thanks to A.Starikov
\setFRMfontfamily{cmr}
\setFRMdfontfamily{ptm}
\setFRMdfontsize{10pt}
% задает длину поля для подписи на титульной странице
\newFRMfield{xtitlesign}{32mm}
% поле для факультета или кафедры
\newFRMfield{fcath}{65mm}
%имя файла с библиографией в формате BibTex
\addbibresource{rbiblio.bib}
\begin{document}
% счетчики страниц, рисунков, таблиц
\regtotcounter{page}
\regtotcounter{figure}
\regtotcounter{table}
\renewcommand{\refname}{\centerline{СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ}}
\renewcommand{\contentsname}{\centerline{СОДЕРЖАНИЕ}}
%\renewcommand{\refname}{Список источников} % По умолчанию "Список литературы" (article)
%\renewcommand{\bibname}{Литература} % По умолчанию "Литература" (book и report)
% титульная страница
\thispagestyle{empty}
\begin{center} \small
\textbf{МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ}\\
ФЕДЕРАЛЬНОЕ ГОСУДАРСТВЕННОЕ АВТОНОМНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ОБРАЗОВАНИЯ\\
«Национальный исследовательский ядерный университет «МИФИ»\\
\textbf{Обнинский институт атомной энергетики} – \\
филиал федерального государственного автономного образовательного учреждения высшего\\
образования «Национальный исследовательский ядерный университет «МИФИ»\\
(ИАТЭ НИЯУ МИФИ)
\end{center}
%\vfill
\medskip
% Направление подготовки следует уточнять,
% магистры и бакалавры могут иметь разные наименования
\begin{center}
\begin{tabular}{rl}
Отделение & \useFRMfield{fcath}[\large Интеллектуальные кибернетические системы] \\
Направление подготовки & \useFRMfield{fcath}[\large Информационные системы и технологии] \\
\end{tabular}
\end{center}
\vfill
\large
\begin{center}
Научно-исследовательская работа \\
\medskip
\textbf{\Large
Разработка скриптов на языке Python для обработки и анализа метеоданных
}
\end{center}
\vspace{1cm}
\begin{tabular*}{\textwidth}{lcr}
Студент группы ИС-Б18 & \useFRMfield{xtitlesign} & Липинский Я. Д.\\
& & \\
Руководитель & & \\
к.т.н., доцент отд. ИКС & \useFRMfield{xtitlesign} & Мирзеабасов О. А.
\end{tabular*}
\vfill
\large
\begin{center}
Обнинск, 2022 г
\end{center}
\onehalfspacing
\pagebreak
% реферат
\thispagestyle{empty}
\section*{\centering РЕФЕРАТ}
% возможно, кол-во источников придется вставлять вручную
Работа \total{page} стр., \total{table} табл., \total{figure} рис. , \totalmycitecounts ист.
ЯЗЫК ПРОГРАММИРОВАНИЯ PYTHON, NUMPY, STATSMODELS, PANDAS, АНАЛИЗ ВРЕМЕННЫХ РЯДОВ, МЕТЕОДАННЫЕ, ВРЕМЕННЫЕ РЯДЫ.
Научно-исследовательская работа посвящена разработке сценариев анализа динамики метеопараметров. Конечная цель работы – создание сценариев на языке Python для вывода значений декомпозиции метеопараметров в файл, построения графиков размаха температур и визуализации трендов и случайных составляющих данных по температуре.
Процесс разработки включает в себя изучение методов декомпозиции временных рядов, языка прогаммирования Python, библиотеки Statsmodels, предоставляющей набор методов статистического тестирования и моделирования, библиотеки Pandas для обработки и анализа данных.
\pagebreak
\thispagestyle{empty}
\section*{\centering ОПРЕДЕЛЕНИЯ, ОБОЗНАЧЕНИЯ И СОКРАЩЕНИЯ}
DataFrame (датафрейм) – распределенная коллекция данных в виде именованных столбцов, аналогично таблице в реляционной базе данных.
NumPy - Numerical Python
БД - База Данных
ВМО - Всемирная Метеорологическая Организация
\pagebreak
\thispagestyle{empty}
% титульная страница - номер 1, остальные страницы до Содержания не нумеруются
\tocloftpagestyle{empty}
\tableofcontents
% если нужно добавить "Стр." над номерами страниц - раскомментируйте следующую команду
%\addtocontents{toc}{~\hfill\textbf{Стр.}\par}
\pagebreak
\setcounter{page}{3}
\section*{\centering ВВЕДЕНИЕ}
\addcontentsline{toc}{section}{ВВЕДЕНИЕ}
\input{intro2} % текст введения в файле intro.tex
\pagebreak
%\input{Post_zad}
\pagebreak
\input{part3} % первая глава - в файле part1.tex
\pagebreak
\input{part4} % вторая глава - в файле part2.tex
\pagebreak
% если есть еще разделы - сохраните их в соответствующих файлах и раскомментируйте строки ниже, при необходимости добавьте еще
%\input{part3} % третья глава - в файле part3.tex
%\pagebreak
%\input{part4} % четвертая глава - в файле part4.tex
%\pagebreak
%\input{part5} % пятая глава - в файле part5.tex
%\pagebreak
\section*{\centering ЗАКЛЮЧЕНИЕ}
\addcontentsline{toc}{section}{ЗАКЛЮЧЕНИЕ}
В ходе проделанной работы были созданы сценарии на языке Python для обработки и анализа метеоданных. Были выполнены следующие задачи:
\begin{itemize}
\item разработан скрипт, строящий график размаха температур, высчитывающий межквартильный размах и выводящий значения декомпозиции метеопараметров в файл;
\item разработан скрипт, строящий графики трендов температур для нескольких метеостанций и выводящий значения в файл;
\item разработан скрипт, строящий графики случайной составляющей температур для нескольких метеостанций и выводящий значения в файл.
\end{itemize}
% оформление библиографии - вариант с БД
\pagebreak
\addcontentsline{toc}{section}{СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ}
% ВАЖНО: для корректного отображения в списке литературы ссылок на англ.языке в bibtex-описание источника следует добавить поле
% langid = {english}
\printbibliography
\pagebreak
\renewcommand{\appendixpagename}{\centering Приложения}
\begin{appendices}
\renewcommand{\thesection}{\Asbuk{section}}
\makeatletter
\renewcommand{\theProgram}{\thesection.\@arabic\c@Program}
\makeatother
% каждое приложение задается следующей командой, нумерация - русскими буквами
\section{\centering }
% независимая нумерация листингов в каждом приложении
\setcounter{Program}{0}
\begin{MyCode}
import os
import sys
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sys import argv
from statsmodels.tsa.seasonal import seasonal_decompose
from pandas.plotting import register_matplotlib_converters
script, data_file = argv
register_matplotlib_converters()
original_stdout = sys.stdout
# Считывание и обработка датасетов.
print("Считывание и обработка данных.")
data1 = pd.read_csv(data_file, sep=";", header=None)
data1.columns = ["index", "year", "month", "day",
"temp_quality", "temp_min", "temp_avg",
"temp_max", "precipitation"]
df1 = pd.DataFrame({'year': data1["year"],
'month': data1["month"],
'day': data1["day"]})
df1["date"] = pd.to_datetime(df1)
df1["temp_avg"] = pd.to_numeric(data1["temp_avg"],
errors='coerce')
df1["temp_min"] = pd.to_numeric(data1["temp_min"],
errors='coerce')
df1["temp_max"] = pd.to_numeric(data1["temp_max"],
errors='coerce')
df1["precipitation"] = pd.to_numeric(data1["precipitation"],
errors='coerce')
meteo_index = str(data1["index"].iloc[0])
# Стилизация графиков.
sns.set_style("darkgrid")
plt.rc("figure", figsize=(12, 9))
plt.rc("font", size=13)
plt.rc("lines", markersize=5)
plt.rc("lines", linewidth=3)
# Создание папки для хранения графиков.
if not os.path.exists("Result"):
os.makedirs("Result")
# Построения графика среднегодовой температуры.
print("Построения графика среднегодовой температуры (" +
+ meteo_index + ").")
result1 = df1.groupby('year').mean()
plt.plot(result1.index, result1["temp_avg"])
plt.title("Среднегодовая температура (" + meteo_index + ")")
plt.xlabel('Год')
plt.ylabel('Температура (цельсии)')
z = np.polyfit(result1.index, result1['temp_avg'], 1)
p = np.poly1d(z)
plt.plot(result1.index, p(result1.index), "r--")
plt.savefig('Result/' + meteo_index + '_Temperature_Plot.png')
plt.clf()
# Построения графика количества осадков за год.
print("Построения графика количества осадков за год (" +
+ meteo_index + ").")
plt.plot(result1.index, result1['precipitation'])
plt.title("Количество осадков за год (" + meteo_index + ")")
plt.xlabel('Год')
plt.ylabel('Количество осадков')
z = np.polyfit(result1.index, result1['precipitation'], 1)
p = np.poly1d(z)
plt.plot(result1.index, p(result1.index), "r--")
plt.savefig('Result/' + meteo_index + '_Precipitations_Plot.png')
plt.clf()
# Построения диаграммы размаха среднегодовой температуры.
print("Построения диаграммы размаха среднегодовой температуры (" +
+ meteo_index + ").")
sns.boxplot(data=df1, x='month', y='temp_avg')
plt.xlabel('Месяц')
plt.ylabel('Температура (цельсии)')
plt.title('Температура (' + meteo_index + ')')
plt.savefig('Result/' + meteo_index + '_Temperature_Boxplot.png')
plt.clf()
# Декомпозиция данных по температуре.
print("Декомпозиция данных по температуре (" + meteo_index + ").")
result = seasonal_decompose(result1['temp_avg'], model='additive',
period=12)
result.plot()
plt.savefig('Result/' + meteo_index +
+ '_Temperature_Decomposition.png')
plt.clf()
numpy_array = result.trend.to_numpy()
np.savetxt("Result/" + meteo_index + "_Temperature_Trend.txt",
numpy_array, fmt="%f")
numpy_array = result.seasonal.to_numpy()
np.savetxt("Result/" + meteo_index + "_Temperature_Seasonal.txt",
numpy_array, fmt="%f")
numpy_array = result.resid.to_numpy()
np.savetxt("Result/" + meteo_index + "_Temperature_Residual.txt",
numpy_array, fmt="%f")
# Декомпозиция данных по осадкам.
print("Декомпозиция данных по осадкам (" + meteo_index + ").")
result = seasonal_decompose(result1['precipitation'],
model='additive', period=12)
result.plot()
plt.savefig('Result/' + meteo_index +
+ '_Precipitations_Decomposition.png')
plt.clf()
numpy_array = result.trend.to_numpy()
np.savetxt("Result/" + meteo_index + "_Precipitations_Trend.txt",
numpy_array, fmt="%f")
numpy_array = result.seasonal.to_numpy()
np.savetxt("Result/" + meteo_index + "_Precipitations_Seasonal.txt",
numpy_array, fmt="%f")
numpy_array = result.resid.to_numpy()
np.savetxt("Result/" + meteo_index + "_Precipitations_Residual.txt",
numpy_array, fmt="%f")
# IQR
q75, q25 = np.percentile(result1['temp_avg'], [75, 25])
iqr = q75 - q25
with open('Result/' + meteo_index + '_Temperature_IQR.txt', 'w')
as f:
f.write('IQR = ' + str(iqr))
q75, q25 = np.percentile(result1['precipitation'], [75, 25])
iqr = q75 - q25
with open('Result/' + meteo_index + '_Precipitations_IQR.txt', 'w')
as f:
f.write('IQR = ' + str(iqr))
# Построение графика размаха температур.
print("Построение графика размаха температур (" + meteo_index + ").")
plt.plot(result1.index, result1['temp_max'] -
- result1['temp_min'])
plt.title("Размах температур (" + meteo_index + ")")
plt.xlabel('Год')
plt.ylabel('Температура (цельсии)')
z = np.polyfit(result1.index, result1['temp_max'] -
- result1['temp_min'], 1)
p = np.poly1d(z)
plt.plot(result1.index, p(result1.index), "r--")
plt.savefig('Result/' + meteo_index + '_TemperatureRange_Plot.png')
plt.clf()
print("\nРабота успешно завершена!")
\end{MyCode}
\begin{Program}
\caption{Код реализации скрипта DecomposeToFile.py}\label{app1}
\end{Program}
\begin{MyCode}
import os
import sys
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sys import argv
from statsmodels.tsa.seasonal import seasonal_decompose
from pandas.plotting import register_matplotlib_converters
script, data_file = argv
register_matplotlib_converters()
original_stdout = sys.stdout
if not os.path.exists("Result"):
os.makedirs("Result")
if os.path.exists("Result/Temperature_Trend.txt"):
os.remove("Result/Temperature_Trend.txt")
# Стилизация графиков.
sns.set_style("darkgrid")
plt.rc("figure", figsize=(12, 9))
plt.rc("font", size=13)
plt.rc("lines", markersize=5)
plt.rc("lines", linewidth=3)
plt.xlabel("Дата")
plt.ylabel("Температура")
plt.title("График трендов температур")
# Считывание и обработка данных.
print("Считывание и обработка данных.")
data = pd.read_csv(data_file, dtype=object, sep=";", header=None)
data.columns = ["index", "year", "month", "day", "temp_quality",
"temp_min", "temp_avg", "temp_max", "precipitation"]
data.loc[data['temp_avg'] == '', 'temp_avg'] = 0.0
df = pd.DataFrame({'year': data["year"],
'month': data["month"],
'day': data["day"]})
df["date"] = pd.to_datetime(df)
df["temp_avg"] = pd.to_numeric(data["temp_avg"],
errors='coerce')
df["precipitation"] = pd.to_numeric(data["precipitation"],
errors='coerce')
df["index"] = data["index"]
df['temp_avg'] = df['temp_avg'].interpolate(method='slinear') \
.interpolate(method='linear')
grouped = df.groupby('index')
index_list = df['index'].unique().tolist()
for x in index_list:
elem = grouped.get_group(x).groupby("year").mean()
dec = seasonal_decompose(elem["temp_avg"], model='additive',
period=12)
plt.plot(elem.index.to_numpy(), dec.trend.to_numpy(), label=x)
a = {'index': x,
'year': elem.index,
'trend': dec.trend.to_numpy()
}
b = pd.DataFrame(a)
b.to_csv("Result/Temperature_Trend.txt", header=None,
index=None, sep=';', mode='a')
plt.legend()
plt.savefig('Result/Temperature_Trends_Decomposition.png')
print("Результат сохранён в папку Result.")
\end{MyCode}
\begin{Program}
\caption{Код реализации скрипта TrendCalc.py}\label{app1}
\end{Program}
\begin{MyCode}
import os
import sys
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sys import argv
from statsmodels.tsa.seasonal import seasonal_decompose
from pandas.plotting import register_matplotlib_converters
script, data_file = argv
register_matplotlib_converters()
original_stdout = sys.stdout
if not os.path.exists("Result"):
os.makedirs("Result")
if os.path.exists("Result/Temperature_Residual.txt"):
os.remove("Result/Temperature_Residual.txt")
# Стилизация графиков.
sns.set_style("darkgrid")
plt.rc("figure", figsize=(12, 9))
plt.rc("font", size=13)
plt.rc("lines", markersize=5)
plt.rc("lines", linewidth=3)
plt.xlabel("Дата")
plt.ylabel("Температура")
plt.title("График случайного значения декомпозиции температур")
# Считывание и обработка данных.
print("Считывание и обработка данных.")
data = pd.read_csv(data_file, dtype=object, sep=";", header=None)
data.columns = ["index", "year", "month", "day", "temp_quality",
"temp_min", "temp_avg", "temp_max", "precipitation"]
data.loc[data['temp_avg'] == '', 'temp_avg'] = 0.0
df = pd.DataFrame({'year': data["year"],
'month': data["month"],
'day': data["day"]})
df["date"] = pd.to_datetime(df)
df["temp_avg"] = pd.to_numeric(data["temp_avg"],
errors='coerce')
df["precipitation"] = pd.to_numeric(data["precipitation"],
errors='coerce')
df["index"] = data["index"]
df['temp_avg'] = df['temp_avg'].interpolate(method='slinear') \
.interpolate(method='linear')
grouped = df.groupby('index')
index_list = df['index'].unique().tolist()
for x in index_list:
elem = grouped.get_group(x).groupby("year").mean()
dec = seasonal_decompose(elem["temp_avg"], model='additive',
period=12)
plt.plot(elem.index.to_numpy(), dec.resid.to_numpy(), label=x)
a = {'index': x,
'year': elem.index,
'residual': dec.resid.to_numpy()
}
b = pd.DataFrame(a)
b.to_csv("Result/Temperature_Residual.txt", header=None,
index=None, sep=';', mode='a')
plt.legend()
plt.savefig('Result/Temperature_Residual_Decomposition.png')
print("Результат сохранён в папку Result.")
\end{MyCode}
\begin{Program}
\caption{Код реализации скрипта ResidCalc.py}\label{app1}
\end{Program}
\end{appendices}
\end{document}