How to efficiently determine if a column of a matrix is made of integers

Which is the most efficient way to determine if the columns of a matrix are all integers, e.g. a = [1 1.5 2; 10 3.1 3] columns 1 and 3 ?

Note that if I would have defined a = Any[1 1.5 2; 10 3.1 3] I could have used

julia> identity.(a[:,1])
2-element Vector{Int64}:
  1
 10 

and then use eltype, but it doesn’t work if a has been already cast to a matrix of Floats and I don’t know its content a priori.

I can use try/catch with convert, but I feel it would be even more inefficient…

julia> isinteger.(Any[1 1.5 2; 10 3.1 3])
2×3 BitMatrix:
 1  0  1
 1  0  1
2 Likes

Thanks, I wasn’t aware of the specific isinteger function. Contrary to identity it works also for Float converted matrices:

julia> a = [1 1.5 2; 10 3.1 3]
2×3 Matrix{Float64}:
  1.0  1.5  2.0
 10.0  3.1  3.0

julia> all(isinteger.(a[:,1]))
true

Better try to avoid slicing and broadcasting, by using the all(func, arr) version, with a dimension keyword:

julia> a = [1 1.5 2; 10 3.1 3]
2×3 Matrix{Float64}:
  1.0  1.5  2.0
 10.0  3.1  3.0

julia> all(isinteger, a; dims=1)
1×3 Matrix{Bool}:
 1  0  1
3 Likes

Actually, this didn’t directly work for me, as in some cases I have string.

I solved with:

isinteger_bml(_)          = false
isinteger_bml(_::Integer) = true
isinteger_bml(x::AbstractFloat)   = isinteger(x)

I don’t know why there isn’t an isinteger() defaulting to false for all non integer types (except Nothing and Missing)

Because we have no way of know that’s correct for novel numeric types. It would arguably be fine for non-numeric types, but then again why are you calling isinteger on values that aren’t even numbers?

1 Like

You can skip the variable entirely, like this:

isinteger_bml(::Integer) = true

You mean non-numeric? I think it makes more sense to assume that asking if e.g. a Dict is an integer is a bug, rather than a just returning false.

2 Likes