朱莉娅:为任何缺少值的向量创建一个方法 [英] Julia: creating a method for Any vector with missing values
问题描述
我想创建一个处理缺失值的函数.但是,当我尝试指定缺少的类型Array {Missing,1}时,它会出错.
function f(x::Array{<:Number, 1})
# do something complicated
println("no missings.")
println(sum(x))
end
function f(x::Array{Missing, 1})
x = collect(skipmissing(x))
# do something complicated
println("removed missings.")
f(x)
end
f([2, 3, 5])
f([2, 3, 5, missing])
我了解我的类型不是Missing,而是Array{Union{Missing, Int64},1}
当我指定此类型时,它在上述情况下有效.但是,我想使用所有类型(字符串,浮点数等,不仅限于Int64
).
我尝试了
function f(x::Array{Missing, 1})
...
end
但是又出错了……说
f (generic function with 1 method)
ERROR: LoadError: MethodError: no method matching f(::Array{Union{Missing, Int64},1})
Closest candidates are:
f(::Array{Any,1}) at ...
我怎么能说我将工会遗漏与任何东西联系在一起?
编辑(重新格式化)
我们有这四个向量和两个处理字符串和数字的函数.
x1 = [1, 2, 3]
x2 = [1, 2, 3, missing]
x3 = ["1", "2", "3"]
x4 = ["1", "2", "3", missing]
function f(x::Array{<:Number,1})
println(sum(x))
end
function f(x::Array{String,1})
println(join(x))
end
f(x)
不适用于x2和x3,因为它们分别是Array{Union{Missing, Int64},1}
和Array{Union{Missing, String},1}
类型.
可能只有一个 函数,该函数可以检测矢量是否包含缺失,然后将其删除,然后对其进行适当处理.
例如:
function f(x::Array{Any, 1})
x = collect(skipmissing(x))
print("removed missings")
f(x)
end
但这不起作用,因为Any
表示混合类型(例如,字符串和数字),并不表示字符串或数字或任何其他形式.
编辑2部分修复
这有效:
function f(x::Array)
x = collect(skipmissing(x))
print("removed missings")
f(x)
end
[但是,如何指定数组的形状(维数)...? (虽然这可能是不相关的主题)]
您可以通过以下方式进行操作:
function f(x::Vector{<:Number})
# do something complicated
println("no missings.")
println(sum(x))
end
function f(x::Vector{Union{Missing,T}}) where {T<:Number}
x = collect(skipmissing(x))
# do something complicated
println("removed missings.")
f(x)
end
现在可以正常工作了:
julia> f([2, 3, 5])
no missings.
10
julia> f([2, 3, 5, missing])
removed missings.
no missings.
10
我将尝试回答提出的问题(如果我错过了什么,请添加评论).
第一个Vector{Union{Missing, <:Number}}
与Vector{Union{Missing, Number}}
相同,这是因为它的作用域规则如 tibL 表示为Vector{Union{Missing, <:Number}}
转换为Array{Union{Missing, T} where T<:Number,1}
,并且where
子句位于Array
内部.
第二(这里我不确定这是否是您想要的).我了解您需要以下行为:
julia> g(x::Array{>:Missing,1}) = "$(eltype(x)) allows missing"
g (generic function with 2 methods)
julia> g(x::Array{T,1}) where T = "$(eltype(x)) does not allow missing"
g (generic function with 2 methods)
julia> g([1,2,3])
"Int64 does not allow missing"
julia> g([1,2,missing])
"Union{Missing, Int64} allows missing"
julia> g(["a",'a'])
"Any allows missing"
julia> g(Union{String,Char}["a",'a'])
"Union{Char, String} does not allow missing"
请注意最后两行-尽管["a", 'a']
不包含丢失的数组,但数组具有Any
元素类型,因此可能包含丢失的内容.最后一种情况除外.
还可以看到,您可以将Array{T,N}
的第二个参数更改为其他参数,以获得不同的尺寸.
此示例之所以有效,是因为第一种方法(更具体地讲)捕获了所有允许Missing
的情况,而第二种方法(更一般地)捕获了剩余的内容(即本质上不允许Missing
的内容). /p>
I would like to create a function that deals with missing values. However, when I tried to specify the missing type Array{Missing, 1}, it errors.
function f(x::Array{<:Number, 1})
# do something complicated
println("no missings.")
println(sum(x))
end
function f(x::Array{Missing, 1})
x = collect(skipmissing(x))
# do something complicated
println("removed missings.")
f(x)
end
f([2, 3, 5])
f([2, 3, 5, missing])
I understand that my type is not Missing but Array{Union{Missing, Int64},1}
When I specify this type, it works in the case above. However, I would like to work with all types (strings, floats etc., not only Int64
).
I tried
function f(x::Array{Missing, 1})
...
end
But it errors again... Saying that
f (generic function with 1 method)
ERROR: LoadError: MethodError: no method matching f(::Array{Union{Missing, Int64},1})
Closest candidates are:
f(::Array{Any,1}) at ...
How can I say that I wand the type to be union missings with whatever?
EDIT (reformulation)
Let's have these 4 vectors and two functions dealing with strings and numbers.
x1 = [1, 2, 3]
x2 = [1, 2, 3, missing]
x3 = ["1", "2", "3"]
x4 = ["1", "2", "3", missing]
function f(x::Array{<:Number,1})
println(sum(x))
end
function f(x::Array{String,1})
println(join(x))
end
f(x)
doesn't work for x2 and x3, because they are of type Array{Union{Missing, Int64},1}
and Array{Union{Missing, String},1}
, respectively.
It is possible to have only one function that detects whether the vector contains missings, removes them and then deals appropriately with it.
for instance:
function f(x::Array{Any, 1})
x = collect(skipmissing(x))
print("removed missings")
f(x)
end
But this doesn't work because Any
indicates a mixed type (e.g., strings and nums) and does not mean string OR numbers or whatever.
EDIT 2 Partial fix
This works:
function f(x::Array)
x = collect(skipmissing(x))
print("removed missings")
f(x)
end
[But how, then, to specify the shape (number of dimensions) of the array...? (this might be an unrelated topic though)]
You can do it in the following way:
function f(x::Vector{<:Number})
# do something complicated
println("no missings.")
println(sum(x))
end
function f(x::Vector{Union{Missing,T}}) where {T<:Number}
x = collect(skipmissing(x))
# do something complicated
println("removed missings.")
f(x)
end
and now it works:
julia> f([2, 3, 5])
no missings.
10
julia> f([2, 3, 5, missing])
removed missings.
no missings.
10
EDIT:
I will try to answer the questions raised (if I miss something please add a comment).
First Vector{Union{Missing, <:Number}}
is the same as Vector{Union{Missing, Number}}
because of the scoping rules as tibL indicated as Vector{Union{Missing, <:Number}}
translates to Array{Union{Missing, T} where T<:Number,1}
and where
clause is inside Array
.
Second (here I am not sure if this is what you want). I understand you want the following behavior:
julia> g(x::Array{>:Missing,1}) = "$(eltype(x)) allows missing"
g (generic function with 2 methods)
julia> g(x::Array{T,1}) where T = "$(eltype(x)) does not allow missing"
g (generic function with 2 methods)
julia> g([1,2,3])
"Int64 does not allow missing"
julia> g([1,2,missing])
"Union{Missing, Int64} allows missing"
julia> g(["a",'a'])
"Any allows missing"
julia> g(Union{String,Char}["a",'a'])
"Union{Char, String} does not allow missing"
Note the last two line - although ["a", 'a']
does not contain missing the array has Any
element type so it might contain missing. The last case excludes it.
Also you can see that you could change the second parameter of Array{T,N}
to something else to get a different dimensionality.
Also this example works because the first method, as more specific, catches all cases that allow Missing
and a second method, as more general, catches what is left (i.e. essentially what does not allow Missing
).
这篇关于朱莉娅:为任何缺少值的向量创建一个方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!