我正尝试在Julia中编写一个函数,该函数接受一个多维数组(一个数据立方体),并将每个条目从0重新缩放为1。
LoadError: MethodError: no method matching -(::Array{Float64,2}, ::Float64)
Closest candidates are:
-(::Float64, ::Float64) at float.jl:397
-(::Complex{Bool}, ::Real) at complex.jl:298
-(::Missing, ::Number) at missing.jl:97
...
Stacktrace:
[1] rescale_zero_one(::Array{Float64,2}) at D:\Julio\Documents\Michigan_v2\CS\EECS_598_Data_Science\codex\Codex_3\svd_video.jl:40
[2] top-level scope at D:\Julio\Documents\Michigan_v2\CS\EECS_598_Data_Science\codex\Codex_3\svd_video.jl:50 [inlined]
[3] top-level scope at .\none:0
in expression starting at D:\Julio\Documents\Michigan_v2\CS\EECS_598_Data_Science\codex\Codex_3\svd_video.jl:48我知道我的函数必须做什么的基础知识,但我真的不理解一些符号,错误告诉我的是什么,或者如何修复它。
function rescale_zero_one(A::Array)
B = float(A)
B -= minimum(B)
B /= maximum(B)
return B
end
m,n,j = size(movie_cube)
println(j)
C = Array{Float64}(UndefInitializer(),m,n,j)
for k in 1:j
println(k)
C[:,:,j] = rescale_zero_one(movie_cube[:,:,j])
end变量movie_cube是一个包含Float64条目的三维数据数组,我只想将这些条目从0重新缩放为1。然而,我提到的错误不断出现。我真的很感谢任何人对这段代码的帮助!
发布于 2019-02-01 09:02:29
尝试使用点语法在数组中执行一些操作!
function rescale_zero_one(A::Array)
B = float.(A)
B .-= minimum(B)
B ./= maximum(B)
return B
end发布于 2019-02-01 17:32:03
这段代码更快、更简单(它只对输入矩阵进行两次传递,而不是前一个答案中的五次传递):
function rescale(A::Matrix)
(a, b) = extrema(A)
return (A .- a) ./ (b - a)
end这可以推广到三维,这样您就不需要在C中的维度上使用外部循环。警告:这个解决方案实际上有点慢,因为在使用dims关键字时,extrema/maximum/minimum很慢,这很奇怪:
function rescale(A::Array{T, 3}) where {T}
mm = extrema(A, dims=(1,2))
a, b = first.(mm), last.(mm)
return (A .- a) ./ (b .- a)
end现在您只需编写C = rescale(movie_cube)即可。您甚至可以进一步推广这一点:
function rescale(A::Array{T, N}; dims=ntuple(identity, N)) where {T,N}
mm = extrema(A, dims=dims)
a, b = first.(mm), last.(mm)
return (A .- a) ./ (b .- a)
end现在,您可以将多维数组标准化为您喜欢的任何维数。当前行为变成
C = rescale(movie_cube, dims=(1,2))重新调整每行的比例是
C = rescale(movie_cube, dims=(1,))默认行为是重新缩放整个数组:
C = rescale(movie_cube)还有一件事,这有点奇怪:
C = Array{Float64}(UndefInitializer(),m,n,j)这没有错,但更常见的是使用更短和更优雅的:
C = Array{Float64}(undef, m, n, j)您还可以考虑简单地编写:C = similar(movie_cube)或C = similar(movie_cube, Float64)。
编辑:另一个一般的解决方案是不在rescale函数中实现维度处理,而是利用mapslices。然后:
function rescale(A::Array)
(a, b) = extrema(A)
return (A .- a) ./ (b - a)
end
C = mapslices(rescale, A, dims=(1,2))这也不是最快的解决方案,原因我不明白。我真的认为这应该很快,而且在未来的Julia版本中可能会更快。
https://stackoverflow.com/questions/54470529
复制相似问题