Документация Engee
Notebook

Загрузка данных и обработка пропусков

В данном примере будет продемонстрирован процесс загрузки данных из формата XLSX и заполнение пропусков в них с помощью библиотек Impute и DataInterpolations.

Данные представляют собой архив наблюдений погодных явлений на одной метеостанции за последние 5 лет. В примере будут использоваться только ежедневные измерения температуры.

Установка библиотек, необходимых для загрузки и обработки данных:

In [ ]:
Pkg.add( "Impute" ); #загрузка библиотеки обработки данных
Pkg.add( "DataInterpolations" );
   Resolving package versions...
  No Changes to `/user/.project/Project.toml`
  No Changes to `/user/.project/Manifest.toml`
   Resolving package versions...
  No Changes to `/user/.project/Project.toml`
  No Changes to `/user/.project/Manifest.toml`

Вызов библиотек, необходимых для загрузки и обработки данных:

In [ ]:
using DataFrames, CSV, XLSX, Plots, Impute, DataInterpolations, Statistics
using Impute: Substitute, impute

Чтение данных из файла в переменную:

In [ ]:
xf_missing = XLSX.readxlsx("$(@__DIR__)/data_for_analysis_missing.xlsx");

Просмотр имён листов в загруженных данных:

In [ ]:
XLSX.sheetnames(xf_missing)
Out[0]:
1-element Vector{String}:
 "data"

Определение данных из файла как датафрейм:

In [ ]:
df_missing = DataFrame(XLSX.readtable("$(@__DIR__)/data_for_analysis_missing.xlsx", "data"));

Подключение бэкэнда - метода отображения графики:

In [ ]:
gr()
Out[0]:
Plots.GRBackend()

Определение переменных, характеризующих данные - время и температуру:

In [ ]:
x = df_missing.Time;
y = df_missing.T;

Построение графика зависимости температуры от времени по исходным данным:

In [ ]:
plot(x, y, labels="Температура", title="График зависимости температуры от времени")
Out[0]:

По графику видно, что в данных есть пропуски, их можно заполнить используя библиотеки Impute и DataInterpolations.

Использование библиотеки Impute:

Определение вектора и матрицы с данными:

In [ ]:
vectorT = df_missing[:,2]
matrixT = df_missing[:,1:2]
typeof(vectorT)
Out[0]:
Vector{Any} (alias for Array{Any, 1})

Конвертация вектора и матрицы в формат, приемлемый для функций библиотеки Impute:

In [ ]:
vectorT = convert(Vector{Union{Missing,Float64}}, vectorT);
matrixT[:,2] = convert(Vector{Union{Missing,Float64}}, matrixT[:,2]);

Заполнение пропусков с помощью интерполяции, фильтрации и среднего значения:

In [ ]:
lin_inter_vectorT = Impute.interp(vectorT); #заполнение пропущенных значений интерполированными (для сигналов)
filter_matrixT = Impute.filter(matrixT; dims=:rows); #удаление объектов/наблюдений с пропущенными данными
mean_matrixT = impute(matrixT[:,2], Substitute(; statistic=mean)); #заполнение пропущенных значений средними значениями (подходит для статистических данных)

Построение графиков с исправленными данными:

In [ ]:
p2 = plot(df_missing[:,1], lin_inter_vectorT, xlabel="Дата", ylabel="Температура", title="Заполнение пропусков линейной интерполяцией", titlefont=font(10));
p3 = plot(df_missing[:,1], mean_matrixT, xlabel="Дата", ylabel="Температура", title="Заполнение пропусков средним значением", titlefont=font(10), guidefont=font(8));
p1 = scatter(df_missing[:,1], df_missing[:,2], markersize=2, xlabel="Дата", ylabel="Температура", title="Исходные данные", titlefont=font(10), guidefont=font(8))
plot(p1, p2, p3,  layout=(3, 1), legend=false)
Out[0]:

Использование библиотеки DataInterpolations

Подготовка данных для применения методов интерполяции:

In [ ]:
days = [x for x in 1:length(df_missing[:,2])] #определение вектора от 1 до значения длины массива с данными
t = days
u = reverse(df_missing[:,2]) #сортировка измерений температуры в обратном порядке, от раннего к позднему
u = convert(Vector{Union{Missing,Float64}}, u); #конвертация данных в нужный, для используемых методов, формат

Заполнение пропусков с помощью линейной интерполяции и построение графика с исправленными данными:

In [ ]:
A = LinearInterpolation(u,t)
scatter(t, u, markersize=2, label="Исходные данные") #вывод точечного графика
plot!(A, label="Линейная интерполяция", xlabel="Время", ylabel="Температура") #вывод зависимости температуры от времени
Out[0]:

Заполнение пропусков с помощью квадратичной интерполяции и построение графика с исправленными данными:

In [ ]:
B = QuadraticInterpolation(u,t)
scatter(t, u, markersize=2, label="Исходные данные")#вывод точечного графика
plot!(B, label="Квадратичная интерполяция", xlabel="Время", ylabel="Температура")#вывод зависимости температуры от времени
Out[0]:

Заполнение пропусков с помощью интерполяции последними постоянными значениями и построение графика с исправленными данными:

In [ ]:
C = ConstantInterpolation(u,t)
scatter(t, u, markersize=2, label="Исходные данные")#вывод точечного графика
plot!(C, label="Последние значения", xlabel="Время", ylabel="Температура")#вывод зависимости температуры от времени
Out[0]:

Вывод:

В этом примере были загружены и предобработаны данные измерений температуры. Были применены методы интерполяции и фильтрации.

По полученным графикам видно, что некоторые методы имеют ограничения по применению к данным разного вида.

Так, замена пропусков на среднее значение, больше подходит для статистического анализа, где характеристики данных практически не изменятся.

В случае с квадратичной интерполяцией наблюдается сильное изменение величины сигнала в относительно крупных пропущенных диапазонах, так что он более применим к небольшим разрывам.