工程数据的初级处理
导言
如果没有数据处理,现代工程是不可想象的:传感器读数,声学诊断信号,测试台的测量结果。 所有这些信息都有不同的格式,从简单的文本文件和Excel电子表格到专门的二进制格式,如MAT和WAV。 正确读取,检查,转换和可视化这些数据的能力是研究工程师的基本技能,并且在任何有意义的分析之前。
本文是对工程数据和信号处理的实际介绍. 端到端示例演示了使用信息的整个周期:从常见格式(CSV,XLSX,TXT,MAT,WAV,PNG)下载,初始检查和类型控制,时间戳转换,时间序列可视化,使用快速傅里叶变换的频谱分
来自钢厂的能耗数据和来自轴承组件的各种类型缺陷的声学信号被用作有意义的例子。 掌握这些技术可以形成用于建模和诊断的工程数据准备的整体视图。
加入图书馆
我们将连接用于处理数据、信号和可视化的库。 StatsBase和Statistics将提供统计功能。 CSV,XLSX和MAT将允许您从适当的格式读取数据。 WAV是音频文件。 图像-用于上传图像。 DSP和FFTW用于频谱分析。
for pkg in (["Statistics", "StatsBase", "StatsPlots", "CSV", "DataFrames", "Dates", "XLSX", "MAT", "WAV", "Images", "FileIO", "DSP", "FFTW", "DelimitedFiles"])
try
eval(Meta.parse("using $pkg"))
catch
Pkg.add(pkg)
eval(Meta.parse("using $pkg"))
end
end
include("media_player.jl");
读取包含能耗数据的CSV文件
让我们从最常见的工程数据格式CSV开始。 让我们阅读与钢铁公司的能耗指标的文件。 的CSV。read函数返回一个DataFrame,一个表格结构,其中列按名称可用。 我们将立即推导维度,以便了解数据的规模。
df_energy = CSV.read("Steel_Industry.csv", DataFrame)
println("数据维度: ", size(df_energy))
println("列名称: ", names(df_energy))
初步数据检查
工程师在接收数据时的第一条规则是通过眼睛看数据。 我们将显示第一行和最后一行,列类型。 这将有助于检测问题:遗漏,不正确的类型,意外的值。
println("前10行:")
first(df_energy, 10)
println("\nТипы данных столбцов:")
[names(df_energy) eltype.(eachcol(df_energy))]
日期和时间转换
在工程数据中,时间戳通常存储为字符串。 将date列转换为DateTime格式。 转换后,我们可以计算日期范围和平均测量步骤。 向DataFrame添加新的DateTime列。
df_energy.DateTime = DateTime.(df_energy.date, dateformat"dd/mm/yyyy HH:MM")
println("范围: ", minimum(df_energy.DateTime), " — ", maximum(df_energy.DateTime))
step_sec = mean([Dates.value(dt)/1000 for dt in diff(df_energy.DateTime)])
println("中间的步骤: ", round(step_sec, digits=2), " sec")
时间序列的可视化
图是了解系统行为的最佳方式。 让我们建立一个整个时期的能源消耗图。 在X轴上是时间,在Y千瓦时。 我们看到周期性模式和异常值。
plot(df_energy.DateTime, df_energy.Usage_kWh,
xlabel="时间", ylabel="千瓦小时",
title="能源消耗",
linewidth=0.5, legend=false, size=(900, 350))
从MAT文件读取数据
的MATLAB(。mat)格式是工程实践中的标准。 它可以存储信号,矩阵和结构。 让我们用轴承的声学信号读取文件. Matread函数返回一个字典,其中键是变量名,值是矩阵。
подшипник = matread("Bearing.mat")
println("密钥在文件中: ", keys(подшипник))
println("信号大小正常: ", size(подшипник["normal"]))
将MAT数据转换为矢量
MAT文件中的数据存储为1×N矩阵。 我们使用vec函数将它们转换为一维向量。 现在它是一个普通的Julia数字数组,你可以用它来执行数学运算。
норма = vec(подшипник["normal"])
ролик = vec(подшипник["roller"])
println("数据类型: ", typeof(норма))
println("信号长度: ", length(норма))
println("\nПервые 5 отсчётов нормального сигнала: \n", норма[1:5])
读取WAV音频文件
声学数据通常以音频格式存储。 Wavread函数返回样本数组和采样率。 与MAT不同,这里数据立即表示为矢量。
сигнал_wav, fs_wav = WAV.wavread("Подшипник_1.wav")
println("采样率: ", fs_wav, " 赫兹")
println("持续时间: ", round(length(сигнал_wav)/fs_wav, digits=2), " sec")
在AnyMath中播放音频文件
我们将使用内置音频播放器重现轴承的声学信号。 要播放音频文件,请运行此代码单元格,播放将自动启动。
media_player("$(@__DIR__)/Подшипник_1.wav", mode="audio")
通过FFT进行光谱分析
快速傅立叶变换将信号从时域转换到频域。 它是振动和声学分析的关键工具。 我们将信号居中,应用FFT,并采取幅度谱的模块。 我们将只绘制前半部分(频率从0到奈奎斯特)。
сигнал = норма[1:4000] .- mean(норма[1:4000])
спектр = abs.(fft(сигнал))
N = length(сигнал)
частоты = (0:N÷2-1) * 10000 / N
plot(частоты, спектр[1:N÷2],
xlabel="频率,赫兹", ylabel="的振幅",
title="轴承的声谱",
linewidth=1, legend=false, size=(800, 350))
通过FFT进行数据压缩
实际任务之一是数据压缩。 让我们看看频谱并确定信号的主要能量集中在哪个范围内。 然后我们将只留下几个关键频率分量-这将是一个压缩表示。 代替4000个信号样本,可以存储20个数字。
амплитуды = спектр[1:N÷2]
энергия_общая = sum(амплитуды.^2)
кум_энергия = cumsum(амплитуды.^2) / энергия_общая
plot(частоты, кум_энергия,
xlabel="频率,赫兹", ylabel="储存的能量",
title="光谱的累积能量",
linewidth=2, legend=false, size=(800, 350))
hline!([0.95], linestyle=:dash, label="95%的能量")
选择信息频带
让我们将频率范围划分为20个相等的频段,并计算每个频段的平均幅度。 这将给出可以存储在表中的信号-20数字的紧凑表示。
кол_полос = 20
полосы = range(0, 5000, length=кол_полос+1)
признаки_fft = zeros(кол_полос)
for i in 1:кол_полос
маска = (частоты .>= полосы[i]) .& (частоты .< полосы[i+1])
if sum(маска) > 0
признаки_fft[i] = mean(амплитуды[маска])
end
end
bar(1:кол_полос, признаки_fft,
xlabel="乐队号码", ylabel="平均振幅",
title="压缩信号表示(20波段)",
legend=false, size=(700, 300))
阅读图像
让我们阅读图像文件。 让我们显示图像类型及其大小。
изобр = Images.load("image.png")
println("图像类型: ", typeof(изобр))
println("大小: ", size(изобр))
让我们显示图像。
изобр
将图像转换为数字矩阵
将图像转换为数字矩阵。
каналы = Float64.(Images.channelview(изобр))
каналы = permutedims(каналы, (2, 3, 1))
图像由954×923×4的三维阵列表示。 前两个维度是954行和923列像素。 第三维由四个颜色通道组成:红色、绿色、蓝色和一个alpha透明度通道。 每个值的范围从0到1,其中对于颜色通道0表示无颜色,1表示最大强度,对于alpha通道1表示完全不透明度。
读取带有数据的文本文件
文本文件是最简单的存储格式。 让我们阅读txt文件与环境温度的数值数据,确定值的数量,范围,并输出前5个值。
температура = vec(readdlm("температура.txt"))
println("值的数量: ", length(температура))
println("范围: ", minimum(температура), " ... ", maximum(температура), " °C")
println("前5个值: ", температура[1:5])
从Excel读取数据
Excel文件在业界分布广泛。 同样,让我们读取带有环境湿度数据的xlsx文件。
X = XLSX.readxlsx("влажность.xlsx")
лист = X[1]
влажность = Float64.(лист["A"][2:end])
println("值的数量: ", length(влажность),)
println("范围: ", minimum(влажность), " ... ", maximum(влажность), " %")
println("前5个值: ", влажность[1:5])
数据集转换
当不需要一些原始列,但需要添加来自外部源的新数据时,我们会转换数据集。 删除NSM、WeekStatus、Day_of_week和Load_Type列,然后添加之前加载的温湿度列。
select!(df_energy, Not([:NSM, :WeekStatus, :Day_of_week, :Load_Type]))
println("Столбцы после удаления: \n\n", names(df_energy))
将以前加载的温度和湿度变量添加为新列。 行数必须匹配。
df_energy.Temperature_C = температура
df_energy.Humidity_Pct = влажность
让我们显示更新数据集的前10行。
println("前10行:")
first(df_energy, 10)
将转换后的数据集保存到新的CSV文件。 源文件 Steel_Industry.csv 它保持不变-所有转换都保存在一个新文件中。 Сталелитейные_данные.csv.
CSV.write("Сталелитейные_данные.csv", df_energy)
转换MAT文件
MAT文件中的数据结构也可以用不同的方式表示。 假设我们从试验台收到了4个轴承数据文件:
*H_1_0。垫-全功能轴承;
*B_11_1.辊子元件的垫子故障;
*我_1_1。垫子-内圈故障;
*O_6_1。垫-外圈的故障。
但数据分析模型需要一个不同的结构-一个MAT文件有四个键"正常","辊","内","外",其中:
正常-全功能轴承;
滚轮-滚轮元件故障;
内-内圈故障;
外-外圈故障。
让我们上传第一个文件。
норм_тест = matread("H_1_0.mat")
此文件具有与所需文件不同的数据结构。 让我们显示数据。
норм_тест = норм_тест["H_1_0"]
该文件有一个键 "H_1_0,其中的数据是矩阵。 我们知道声学数据位于第二列。 我们不需要任何其他数据。 让我们提取这些数据。
норм_тест = норм_тест[:,2]
让我们打开其余的MAT文件。
ролик_тест = matread("B_11_1.mat")
внут_тест = matread("I_1_1.mat")
внеш_тест = matread("O_6_1.mat")
让我们提取矩阵。
ролик_тест = ролик_тест["B_11_1"]
внут_тест = внут_тест["I_1_1"]
внеш_тест = внеш_тест["O_6_1"]
接下来,我们将以相同的方式从每个矩阵中提取第二列。
ролик_тест = ролик_тест[:,2]
внут_тест = внут_тест[:,2]
внеш_тест = внеш_тест[:,2]
现在我们有四个包含声学数据的向量。: норм_тест ролик_тест, внут_тест, внеш_тест. 它们必须组装成先前指定结构的单个MAT文件。 让我们用必要的键创建一个字典。
данные = Dict(
"normal" => норм_тест,
"roller" => ролик_тест,
"inner" => внут_тест,
"outer" => внеш_тест)
将此数据保存到新的MAT文件中。
matwrite("Подшипник_тест.mat", данные)
让我们阅读创建的文件。
matread("Подшипник_тест.mat")
创建的文件的结构对应于所需的文件。 数据已准备好供进一步使用。
结论
在这项工作的过程中,考虑了为分析准备工程数据和信号的整个路径。 它展示了如何统一加载来自异构源的信息-表格(CSV,XLSX),文本,二进制(MAT),音频(WAV)和图形格式,以及如何将它们带入适合计算的形式:矢量,矩阵和数据帧表。 演示了数据结构控制、时间戳转换、时间序列可视化、FFT频谱分析和信号压缩到一组紧凑的信息特性的操作。
特别注意数据集的转换:组合来自外部源的表,删除冗余列,以及将不同的MAT文件重新打包到具有指定键的单个结构中。 这些操作反映了典型的工程实践任务,其中数据存储格式与模型或分析方法所需的格式不匹配。 所提出的技术构成了后续阶段的基础–统计处理,构建诊断模型和机器学习。
.png)