首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Julia v1.1中编写输入多维数组的函数?

如何在Julia v1.1中编写输入多维数组的函数?
EN

Stack Overflow用户
提问于 2019-02-01 07:01:49
回答 2查看 390关注 0票数 0

我正尝试在Julia中编写一个函数,该函数接受一个多维数组(一个数据立方体),并将每个条目从0重新缩放为1。

代码语言:javascript
复制
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

我知道我的函数必须做什么的基础知识,但我真的不理解一些符号,错误告诉我的是什么,或者如何修复它。

代码语言:javascript
复制
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。然而,我提到的错误不断出现。我真的很感谢任何人对这段代码的帮助!

EN

回答 2

Stack Overflow用户

发布于 2019-02-01 09:02:29

尝试使用点语法在数组中执行一些操作!

代码语言:javascript
复制
function rescale_zero_one(A::Array)
    B = float.(A)
    B .-= minimum(B)
    B ./= maximum(B)
    return B
end
票数 2
EN

Stack Overflow用户

发布于 2019-02-01 17:32:03

这段代码更快、更简单(它只对输入矩阵进行两次传递,而不是前一个答案中的五次传递):

代码语言:javascript
复制
function rescale(A::Matrix)
    (a, b) = extrema(A)
    return (A .- a) ./ (b - a)
end

这可以推广到三维,这样您就不需要在C中的维度上使用外部循环。警告:这个解决方案实际上有点慢,因为在使用dims关键字时,extrema/maximum/minimum很慢,这很奇怪:

代码语言:javascript
复制
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)即可。您甚至可以进一步推广这一点:

代码语言:javascript
复制
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

现在,您可以将多维数组标准化为您喜欢的任何维数。当前行为变成

代码语言:javascript
复制
C = rescale(movie_cube, dims=(1,2))

重新调整每行的比例是

代码语言:javascript
复制
C = rescale(movie_cube, dims=(1,))

默认行为是重新缩放整个数组:

代码语言:javascript
复制
C = rescale(movie_cube)

还有一件事,这有点奇怪:

代码语言:javascript
复制
C = Array{Float64}(UndefInitializer(),m,n,j)

这没有错,但更常见的是使用更短和更优雅的:

代码语言:javascript
复制
C = Array{Float64}(undef, m, n, j)

您还可以考虑简单地编写:C = similar(movie_cube)C = similar(movie_cube, Float64)

编辑:另一个一般的解决方案是不在rescale函数中实现维度处理,而是利用mapslices。然后:

代码语言:javascript
复制
function rescale(A::Array)
    (a, b) = extrema(A)
    return (A .- a) ./ (b - a)
end

C = mapslices(rescale, A, dims=(1,2))

这也不是最快的解决方案,原因我不明白。我真的认为这应该很快,而且在未来的Julia版本中可能会更快。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54470529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档