朱莉娅:为任何缺少值的向量创建一个方法 [英] Julia: creating a method for Any vector with missing values

查看:99
本文介绍了朱莉娅:为任何缺少值的向量创建一个方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建一个处理缺失值的函数.但是,当我尝试指定缺少的类型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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆