Engee 文档
Notebook

上传数据和处理通行证

此示例将演示从XLSX格式下载数据并使用Impact和DataInterpolations库填补空白的过程。

该数据是一个气象站过去五年的天气观测资料。
在示例中,将仅使用每日温度测量值。

安装下载和处理数据所需的库:

In [ ]:
Pkg.add(["Statistics", "XLSX", "Impute", "CSV", "DataInterpolations"])
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"

将文件中的数据定义为dataframe:

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]:

图表显示数据中存在空白,可以使用库Impact和DataInterpolations来填充这些空白。

使用影响库:

定义向量和数据矩阵:

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

将向量和矩阵转换为影响库函数可接受的格式:

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]:

结论:

在这个例子中,温度测量数据被上传和预处理。 应用了插值和滤波方法。

根据得到的图表可以看出,有些方法在应用于不同类型的数据方面存在局限性。

因此,用平均值替换遗漏更适合统计分析,其中数据的特征不会发生太大变化。

在二次插值的情况下,在相对较大的缺失范围内信号的量值存在较强的变化,从而更适用于小间隙。