为什么 isless(0 , missing) returns true 但 0<missing returns 在 Julia 中缺失?

Why isless(0 , missing) returns true but 0<missing returns missing in Julia?

我今天遇到了 Julia 的奇怪行为,那是我试图比较 missing0 的时候!如果你在 REPL 中尝试这个 0<missing:

julia> 0<missing
missing

但是如果您尝试使用这样的预建 isless 函数:

julia> isless(0 , missing)
true

这很奇怪,因为 0<missing 意味着 0 is less than missingisless(0 , missing) 相同。根据 isless 文档:

isless(t1::Tuple, t2::Tuple)
Returns true when t1 is less than t2 in lexicographic order.

不应该0<missing return true吗?

来自文档:

Standard equality and comparison operators follow the propagation rule presented above: if any of the operands is missing, the result is missing.

julia> missing < 1
missing

julia> 2 >= missing
missing

然后,下面一点:

The isless operator is another exception: missing is considered as greater than any other value. This operator is used by sort, which therefore places missing values after all other values.

julia> isless(1, missing)
true

julia> isless(missing, Inf)
false

julia> isless(missing, missing)
false

所以这似乎是设计使然:
https://docs.julialang.org/en/v1/manual/missing/#Propagation-of-Missing-Values

现在如果你的问题是为什么要这样设计,那么也许 Julia 的设计师会过来开导我们:)

missing < 0 生成 missing 因为 < 是“标准”比较运算符。

现在考虑一个问题:missing是否小于0?答案是:我们不知道。 missing 代表某个未知值 - 它可以大于或小于 0。因此 missing < 0 产生 missing.

如您在 < 的文档中所见:

this operator implements a partial order.

这意味着它不保证所有值都具有可比性。类似(但不相同)的情况是 NaN:

julia> NaN < 0.0
false

julia> NaN > 0.0
false

julia> NaN == 0.0
false

还要注意,虽然 -0.00.0 是不同的浮点值,但我们有:

julia> -0.0 < 0.0
false

现在让我们讨论isless。它是必需的,因为有时您需要一个定义总顺序的运算符,如您在其文档中所见:

Test whether x is less than y, according to a fixed total order (defined together with isequal).

这在您想要确保可以安全地假设每个值都具有可比性的情况下很有用。例如 sort 使用 isless.

现在为了确保 isless 定义总顺序,我们需要定义 missing 在此总顺序中的位置。决定 missing 大于任何其他值。因此 isless(missing, 0)false。当然,这是一个武断的决定。它被制作成例如当你 sort 向量 missing 放在末尾:

julia> sort([1, missing, 2])
3-element Vector{Union{Missing, Int64}}:
 1
 2
  missing

这是人们通常想要的。

现在注意 NaN-0.0 的行为:

julia> isless(NaN, missing)
true

julia> isless(Inf, NaN)
true

julia> isless(-0.0, 0.0)
true

如您所见,NaN 大于 Inf 但小于 missing 并且 -0.0 小于 0.0。再次 - 因为 isless 是一个总顺序,所以不同的值必须放在这个总顺序中的不同位置。