Skip to content

Commit

Permalink
nanbinmean must be able to dispatch to weighted version
Browse files Browse the repository at this point in the history
  • Loading branch information
brenhinkeller committed Jun 5, 2021
1 parent d9e8cef commit 17db2e9
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 18 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "NaNStatistics"
uuid = "b946abbf-3ea7-4610-9019-9858bfdeaf2d"
authors = ["C. Brenhin Keller"]
version = "0.3.1"
version = "0.4.0"

[deps]
IfElse = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173"
Expand All @@ -15,7 +15,7 @@ IfElse = "0.1"
LoopVectorization = "0.11, 0.12"
StatsBase = "0.28 - 0.33"
VectorizationBase = "0.18, 0.19, 0.20"
julia = "1.5"
julia = "1"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
14 changes: 7 additions & 7 deletions src/Binning.jl
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
`y` will be treated as a separate variable.
"""
# In-place binning with weights; y, W, MU as 1D vectors
function nanbinwmean!(MU::AbstractVector, W::AbstractVector, x::AbstractVector, y::AbstractVector, w::AbstractVector, xedges::AbstractRange)
function nanbinmean!(MU::AbstractVector, W::AbstractVector, x::AbstractVector, y::AbstractVector, w::AbstractVector, xedges::AbstractRange)
# What is the size of each bin?
nbins = length(xedges) - 1
xmin, xmax = extrema(xedges)
Expand Down Expand Up @@ -194,7 +194,7 @@
return MU
end
# In-place binning with weights; y, W, MU as 2D matrices
function nanbinwmean!(MU::AbstractMatrix, W::AbstractMatrix, x::AbstractVector, y::AbstractMatrix, w::AbstractVector, xedges::AbstractRange)
function nanbinmean!(MU::AbstractMatrix, W::AbstractMatrix, x::AbstractVector, y::AbstractMatrix, w::AbstractVector, xedges::AbstractRange)
nbins = length(xedges) - 1
xmin, xmax = extrema(xedges)
δ𝑖δx = nbins / (xmax - xmin)
Expand Down Expand Up @@ -230,7 +230,7 @@

return MU
end
nanbinwmean!(MU, W, x, y, w, xmin::Number, xmax::Number, nbins::Integer) = nanbinwmean!(MU, W, x, y, w, range(xmin,xmax,length=nbins+1))
nanbinmean!(MU, W, x, y, w, xmin::Number, xmax::Number, nbins::Integer) = nanbinmean!(MU, W, x, y, w, range(xmin,xmax,length=nbins+1))


"""
Expand Down Expand Up @@ -371,7 +371,7 @@

"""
```julia
nanbinwmean(x, y, xedges::AbstractRange)
nanbinmean(x, y, xedges::AbstractRange)
```
Ignoring NaNs, calculate the weighted mean of `y` values that
fall into each of `length(xedges)-1` equally spaced bins along the `x`
Expand All @@ -382,12 +382,12 @@
AbstractVecOrMat). If `y` is a 2-d array, then each column of `y` will be
treated as a separate variable.
"""
function nanbinwmean(x::AbstractVector, y::AbstractVecOrMat, w::AbstractVector, xedges::AbstractRange)
function nanbinmean(x::AbstractVector, y::AbstractVecOrMat, w::AbstractVector, xedges::AbstractRange)
W = Array{float(eltype(y))}(undef, length(xedges)-1, size(y)[2:end]...)
MU = Array{float(eltype(y))}(undef, length(xedges)-1, size(y)[2:end]...)
return nanbinwmean!(MU, W, x, y, w, xedges)
return nanbinmean!(MU, W, x, y, w, xedges)
end
nanbinwmean(x, y, w, xmin::Number, xmax::Number, nbins::Integer) = nanbinwmean(x, y, w, range(xmin,xmax,length=nbins+1))
nanbinmean(x, y, w, xmin::Number, xmax::Number, nbins::Integer) = nanbinmean(x, y, w, range(xmin,xmax,length=nbins+1))


"""
Expand Down
18 changes: 9 additions & 9 deletions test/testBinning.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
@test nanbinmean(1:100, reshape(1:300,100,3), range(0,100,length=4)) == r

# Weighted means
@test NaNStatistics.nanbinwmean([1:100..., 1], [1:100..., NaN], ones(101), 0,100,3) == [17, 50, 83]
@test NaNStatistics.nanbinwmean([1:100..., 1], [1:100..., NaN], ones(101), range(0,100,length=4)) == [17, 50, 83]
@test NaNStatistics.nanbinwmean(1:100, reshape(1:300,100,3), ones(101), 0, 100, 3) == r
@test NaNStatistics.nanbinwmean(1:100, reshape(1:300,100,3), ones(101), range(0,100,length=4)) == r
NaNStatistics.nanbinwmean!(M33, N33, 1:100, reshape(1:300,100,3), ones(101), 0, 100, 3)
@test nanbinmean([1:100..., 1], [1:100..., NaN], ones(101), 0,100,3) == [17, 50, 83]
@test nanbinmean([1:100..., 1], [1:100..., NaN], ones(101), range(0,100,length=4)) == [17, 50, 83]
@test nanbinmean(1:100, reshape(1:300,100,3), ones(101), 0, 100, 3) == r
@test nanbinmean(1:100, reshape(1:300,100,3), ones(101), range(0,100,length=4)) == r
nanbinmean!(M33, N33, 1:100, reshape(1:300,100,3), ones(101), 0, 100, 3)
@test M33 == r
@test N33 == fill(33,3,3)

Expand Down Expand Up @@ -70,18 +70,18 @@
M2 = zeros(2)
N2 = fill(0,2)
w = "length(MU) < nbins; any bins beyond length(MU) will not be filled"
@test_logs (:warn, w) NaNStatistics.nanbinwmean!(M2, N2, [1:100..., 1],[1:100..., NaN],ones(101), 0,100,3)
@test_logs (:warn, w) NaNStatistics.nanbinmean!(M2, N2, [1:100..., 1],[1:100..., NaN],ones(101), 0,100,3)
@test M2 == [17, 50]
@test_logs (:warn, w) NaNStatistics.nanbinwmean!(M2, N2, 1:100,1:100,ones(101), 0,100,3)
@test_logs (:warn, w) NaNStatistics.nanbinmean!(M2, N2, 1:100,1:100,ones(101), 0,100,3)
@test M2 == [17, 50]

M23 = zeros(2,3)
N23 = fill(0,2,3)
w = "size(MU,1) < nbins; any bins beyond size(MU,1) will not be filled"
@test_logs (:warn, w) NaNStatistics.nanbinwmean!(M23, N23, 1:100, reshape(1:300,100,3), ones(101), 0, 100, 3)
@test_logs (:warn, w) NaNStatistics.nanbinmean!(M23, N23, 1:100, reshape(1:300,100,3), ones(101), 0, 100, 3)
@test M23 == r[1:2,1:3]
w = "size(MU,2) < size(y,2); any columns beyond size(MU,2) will not be filled"
@test_logs (:warn, w) NaNStatistics.nanbinwmean!(M23', N23', 1:100, reshape(1:300,100,3), ones(101), 0, 100, 3)
@test_logs (:warn, w) NaNStatistics.nanbinmean!(M23', N23', 1:100, reshape(1:300,100,3), ones(101), 0, 100, 3)
@test M23' == r[1:3,1:2]

# 2D case
Expand Down

2 comments on commit 17db2e9

@brenhinkeller
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register

Release notes:

  • nanbinwmean -> nanbinmean
  • nanbinwmean! -> nanbinmean!
  • The weighted versions are now distinguished by number of arguments (as they already are for plain nanmean), allowing dispatch to choose which one applies. This is useful when writing higher-order functions that are given the function handle of a binning function, as in the resampling functions in StatGeochem.jl

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/38246

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.4.0 -m "<description of version>" 17db2e94cb49d316fc6210e5161933bb3adeb1fb
git push origin v0.4.0

Please sign in to comment.