From 347fba716bac91710cbf318cb7a0e49b28b23dae Mon Sep 17 00:00:00 2001 From: Milan Bouchet-Valat Date: Tue, 31 Mar 2020 11:12:47 +0200 Subject: [PATCH] Fix minimum/maximum over dimensions with missing values `v0 != v0` returns `missing` for missing values. Use the largest/smallest non-missing value to initialize the array. This is an inefficient approach. Faster alternatives would be to avoid using an initial value at all, and instead keep track of whether a value has been set in a separate mask; or to use `typemax`/`typemin` for types that support them. --- base/reducedim.jl | 5 ++++- test/reduce.jl | 8 ++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/base/reducedim.jl b/base/reducedim.jl index fe3adef035dec..6722bd704a4ed 100644 --- a/base/reducedim.jl +++ b/base/reducedim.jl @@ -144,7 +144,10 @@ for (f1, f2, initval) in ((:min, :max, :Inf), (:max, :min, :(-Inf))) # otherwise use the min/max of the first slice as initial value v0 = mapreduce(f, $f2, A1) - # but NaNs need to be avoided as initial values + # but missings and NaNs need to be avoided as initial values + if ismissing(v0) && !all(ismissing, A) + v0 = mapreduce(f, $f2, skipmissing(A)) + end v0 = v0 != v0 ? typeof(v0)($initval) : v0 T = _realtype(f, promote_union(eltype(A))) diff --git a/test/reduce.jl b/test/reduce.jl index 69b8b1911e7ea..3a9b598dd22d4 100644 --- a/test/reduce.jl +++ b/test/reduce.jl @@ -325,6 +325,14 @@ end @test maximum(Vector(Int16(1):Int16(100))) === Int16(100) @test maximum(Int32[1,2]) === Int32(2) +@testset "minimum/maximum over dims with missing (#35308)" begin + x = [1 missing; 2 missing] + @test isequal(minimum(x, dims=1), reshape([1, missing], 1, :)) + @test isequal(maximum(x, dims=1), reshape([2, missing], 1, :)) + @test isequal(minimum(x, dims=2), reshape([missing, missing], :, 1)) + @test isequal(maximum(x, dims=2), reshape([missing, missing], :, 1)) +end + A = circshift(reshape(1:24,2,3,4), (0,1,1)) @test extrema(A,dims=1) == reshape([(23,24),(19,20),(21,22),(5,6),(1,2),(3,4),(11,12),(7,8),(9,10),(17,18),(13,14),(15,16)],1,3,4) @test extrema(A,dims=2) == reshape([(19,23),(20,24),(1,5),(2,6),(7,11),(8,12),(13,17),(14,18)],2,1,4)