从Excel格式和构建模型中读取数据
很多时候,需要分析的数据不是从一些抽象的存储库或数据库中获取的,而是存在于某种表格格式的文件中。 在某些行业中,CSV是首选格式;在其他情况下,数据是在标准表格编辑器中创建的。
在本演示中,我们将学习如何在图形上加载和显示Excel电子表格中的数据,并基于它构建模型。
读取整个文件
对于大多数命令,我们将需要以下库,这些库已经内置到环境中。 我们只需要表明我们将使用这些库的命名空间中的命令。
Pkg.add(["Interpolations", "XLSX", "GLM", "Optim"])
using XLSX, DataFrames
一个Excel文件可以包含多个带有表格的工作表。 大多数情况下,我们只使用这些表中的第一个,这被称为 Лист1 或 Sheet1 (但它可能被称为别的东西)。
读取整个文件将返回一个对象,里面有几个表,每个表都位于一个单独的工作表上。
xf = XLSX.readxlsx( "table_simple_example.xlsx" )
我们可以通过显示工作表列表再次验证这一点。
XLSX.sheetnames(xf)
如果您已经使用命令打开文件 readxlsx 然后,您可以使用附加命令分离所需的工作表。
sh = xf["Лист1"]
或者您可以使用更快地执行此过程的命令。
从表中读取单独的工作表
图书馆团队的标准 XLSX 您可以单独阅读每张纸。
XLSX.readtable( "table_simple_example.xlsx", "Лист1" )
你可以把表格的格式 DataFrame 并使用此库处理数据。
DataFrame( XLSX.readtable( "table_simple_example.xlsx", "Лист1" ) )
xdf = Float32.(DataFrame( XLSX.readtable( "table_simple_example.xlsx", "Лист1" ) ))
但是,当数据是一组对象及其属性列表时,这是有意义的。 有时该表只包含一个带有数字的矩阵,然后最好使用标准数据类型来处理它。 Matrix.
xm = XLSX.readdata( "table_simple_example.xlsx", "Лист1", "A2:C4" )
选择正确的数据类型大大简化了表格或矩阵的进一步工作。
gr()
wireframe( xm )
在新的计算网格上计算数据(插值)
现在,我们可以使用某个坐标系中的数据集表,我们可以使用样条进行插值并构建模型。
xm = vec( Float32.( XLSX.readdata("table_matrix_example.xlsx", "Лист1", "B1:D1") ))
ym = vec( Float32.( XLSX.readdata("table_matrix_example.xlsx", "Лист1", "A2:A4") ))
zm = Float32.( XLSX.readdata("table_matrix_example.xlsx", "Лист1", "B2:D4") )
wireframe( xm, ym, zm )
using Interpolations
# Переводим описание системы координат из векторов в набор диапазонов
xSrc = range( minimum(xm), maximum(xm), step=xm[2]-xm[1] )
ySrc = range( minimum(ym), maximum(ym), step=ym[2]-ym[1] )
# Строим модель, которая предскажет нам значения на новой сетке
cubInt = cubic_spline_interpolation( (xSrc, ySrc), zm )
# Задаем новую расчетную сетку
xRange = range( minimum(xm), maximum(xm), 50 )
yRange = range( minimum(ym), maximum(ym), 50 )
zIntRes = cubInt(xRange, yRange)
# Визуализируем результат
surface( xRange, yRange, zIntRes, fillalpha=0.2 )
wireframe!( xRange, yRange, zIntRes )
我们进行了三次样条插值。 如果原始数据点位于坐标系中,但沿着X和Y轴具有不规则的衬线,那么我们将只能基于线性插值(或"最近邻法"模型)构建模型。
函数逼近和最小搜索
在对数据进行可视化分析之后,您可以假设哪个函数可以方便地近似此数据。 这需要一些经验和数据的交互工作。
让我们假设我们已经确保使用二次函数很好地表示数据。 让我们构造一个多项式,使我们能够更准确地找到输出参数的估计值,其中所研究过程的目标值最小。
using GLM
# Подготовим данные: представим таблицу как список отдельных точек данных
xx = Float64.(repeat( collect(xSrc), outer = length(ySrc) ))
yy = Float64.(repeat( collect(ySrc), inner = length(xSrc) ))
zz = Float64.(vec(reshape(zm', 1, :)))
# Создадим объект DataFrame
data = DataFrame( X = xx, Y = yy, Z = zz )
# Построим модель с двумя входными параметрами
model = lm( @formula(Z ~ X + Y + X^2 + Y^2 + X*Y), data )
# Задаем новую расчетную сетку
dx = 2 * abs(maximum(xm) - minimum(xm))
dy = 2 * abs(maximum(ym) - minimum(ym))
xRange = range( minimum(xm) - dx, maximum(xm) + dx, 50 )
yRange = range( minimum(ym) - dy, maximum(ym) + dy, 20 )
# Визуализируем результат
xx = repeat( collect(xRange), outer = length(yRange) )
yy = repeat( collect(yRange), inner = length(xRange) )
zz = reshape( GLM.predict(model, (;X=xx,Y=yy)), length(xRange), :)
# Построим графики
surface( xRange, yRange, zz', fillalpha=0.2, xlabel="x", ylabel="y", zlabel="z" )
wireframe!( xRange, yRange, zz' )
使用以下方法创建的模型 GLM 它们将点云作为输入(如您所见,我们使用了一维向量形式的数据 Vector),并允许您在没有任何额外设置的情况下执行外推。
求极小点
这两个对象都允许我们找到函数的最低点,我们从表中获得了该函数的描述。
using Optim
opt = optimize( x->GLM.predict( model,(;X=[x[1]],Y=[x[2]]) )[1], [0.0,0.0] )
(x_min, y_min) = Optim.minimizer( opt )
surface( xRange, yRange, zz', xlabel="x", ylabel="y", zlabel="z", c=:viridis, zcolor=zz' )
scatter!( [x_min], [y_min], [GLM.predict( model,(;X=[x_min],Y=[y_min]) )[1]],
camera = (30,50), legend=false, cbar=false )
我们收到了一个标记最小值的图表。
将数据写入Excel文件
要将分析结果保存到另一个Excel电子表格,请使用以下命令:
XLSX.openxlsx( "table_write_example_1.xlsx", mode="w" ) do xf
# Поместим матрицу на первый лист
XLSX.rename!( xf[1], "Лист1" )
xw = reshape(xx, 1, :) # Сделаем матрицы из векторов
for ind in CartesianIndices(xw)
XLSX.setdata!( xf["Лист1"], XLSX.CellRef( ind[1], ind[2]+1 ), xw[ind])
end
yw = reshape(yy, :, 1)
for ind in CartesianIndices(yw)
XLSX.setdata!( xf["Лист1"], XLSX.CellRef( ind[1]+1, ind[2] ), yw[ind])
end
zw = zz
for ind in CartesianIndices(zw)
XLSX.setdata!( xf["Лист1"], XLSX.CellRef( ind[1]+1, ind[2]+1 ), zw[ind])
end
# На второй лист поместим DataFrame
XLSX.addsheet!( xf, "Лист2" )
XLSX.writetable!( xf["Лист2"], eachcol(xdf), names(xdf); anchor_cell=XLSX.CellRef("A1"))
end
或者,更短,以节省 DataFrame 在单张表中:
XLSX.writetable( "table_write_example_2.xlsx", xdf, overwrite=true )
保存对象 Matrix 或 Vector 表格格式更常用 CSV.
结论
在这个例子中,我们学习了如何读取Excel表格格式的文件。 我们将它们转换为不同的格式。:
*格式 DataFrame 哪个最适合分析表格数据
*格式 Matrix,它允许您使用源表中的一组数字作为矩阵
我们还演示了如何对从Excel文件读取的数据进行插值和近似,以及如何保存结果。

