I have been trying to filter a 2d-array with boolean indexing without much success. For instance,
B = randn(5,5)
s = B .> 0
B[s] # this produces a 1d array with those values that give s == true
However, since I want is to plot with
contourf those values in
B[s] keeping those that does not satisfy the the
s condition as well. The problem is that I get the 1d-array satisfying the
s conditions instead of the whole 2d-array and the plot does not work with this. What I tried to do to obtain the desired result is
which gives the filtered matrix with the same original size of
B. But not sure if this is an effective way of doing things, especially when lengths of arrays goes up to, say 10^4.
It’s a bit hard to understand what you want the end result to be for the cases where the element is
Perhaps you are looking for
julia> clamp.(B, 0, Inf)
0.0 1.63247 0.0 0.0 0.0
1.23743 0.0191958 0.417646 0.0 1.17548
0.0 0.0 0.42163 0.601486 0.726729
0.0 0.0 0.0 0.0 0.360118
0.420498 0.0 0.0 2.44904 0.0
I was trying to plot with
contourf a complex variable showing only those values that have zero imaginary part, discarding the others, but keeping the same size of the original array. The working example wasn’t probably appropriate enough (noted). Here it goes again:
0.542545+0.0im 0.925355-0.487208im 1.65225+0.806615im
-0.927869+0.847093im -0.309946+1.53378im 0.444565+0.0im
-0.048035+0.260424im 0.937434+0.0im -0.153685-1.71329im
Now, if I do
s = imag.(B) .== 0, then
0.5425454 + 0.0im
0.937434 + 0.0im
0.44456454 + 0.0im
But is hard to plot this way. What I really want is the original matrix
B with those values that have zero imaginary part sent to zero. For instance,
0.542545+0.0im 0.0-0.0im 0.0+0.0im
-0.0+0.0im -0.0+0.0im 0.444565+0.0im
-0.0+0.0im 0.937434+0.0im -0.0-0.0im
Hope is illustrative enough.
Indexing is, at its core, simply a selection API. It chooses which locations you want to have returned. Or modified, in the case of
setindex!. As such, you can use boolean indexing to change the values as you’d like:
B[imag.(B) .== 0] .= 0
clamp is another great tool as @kristoffer.carlsson mentions, as is broadcasted
ifelse.(imag.(B) .== 0, missing, B)
If you’re worried about runtime, the best way to avoid it is to plot fewer points. The plotting library runtime will be orders of magnitude larger than the difference in runtime between indexing methods. Your screen only has so many pixels–you won’t lose much by downsampling your array to the desired plotting resolution.
using Plots, BenchmarkTools
A[imag(A) .< 0] .= 0
function resampled_contour(A, res)
B = A[1:(size(A,1)÷res):end, 1:(size(A,2)÷res):end]
B[imag(B) .< 0] .= 0
@btime full_contour!(A) setup=(A = randn(ComplexF64, 5000, 5000));
@btime resampled_contour($A, 500) setup=(A = randn(ComplexF64, 5000, 5000));
1.180 s (2848 allocations: 670.74 MiB) # full_contour!
12.141 ms (2850 allocations: 10.72 MiB) # resampled_contour
Yeah, both worked. Thank you guys.
Don’t forget comprehension! (Which creates a new matrix.) Also note that you can use
isreal to check for zero imaginary part.
C = [isreal(x) ? 0.0im : x for x in B]
I took for granted that if the variable is actually complex,
isreal would be false independently of the values. Good to know. Thanks.