Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing only zeros in an array with another array's values in Julia

Tags:

arrays

julia

I am trying to replace an array with another array, but only in places where the original array is zero. These arrays are equal in dimensions.

Array1 = [0, 2, 4, 2, 5, 0, 0, 2, 5]
Array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]

I am currently trying to use the code below to superimpose array2 into array 1 where array1's values are equal to zero.

Array1[Array1 .== 0] .= Array2

From this I was hoping to get the following...

Array1 = [1, 2, 4, 2, 5, 6, 7, 2, 5]

but instead I get an error...

ERROR: DimensionMismatch("array could not be broadcast to match destination")

Is there a nice way to do this without looping through each list/array one element at a time? I am working with really large arrays and don't know if that would be too slow. Any help is appreciated.

like image 972
Sean C Avatar asked Dec 20 '20 02:12

Sean C


People also ask

How do you remove an element from an array in Julia?

We can do this with the deleteat! function. (It looks like the function name is “delete eat” but it's actually “delete at” 😂). You can also delete a range of elements from an array using deleteat!()

How do I add an element to an array in Julia?

Julia allows adding new elements in an array with the use of push! command. Elements in an array can also be added at a specific index by passing the range of index values in the splice! function.

Can we change the value of an element in an array?

To change the value of an object in an array:Call the findIndex() method to get the index of the specific object. Access the array at the index and change the property's value using dot notation. The value of the object in the array will get updated in place.


2 Answers

This can be done easily almost the way you have it:

Array1[Array1 .== 0] .= Array2[Array1 .== 0]

The part Array1 .== 0 is creating an array of zeros and ones that has the same length as the original one. Zeros in the places where the condition is not met and ones in the places where the condition is met.

When you do something like:

Array1 .= Array2

You are telling julia to copy Array2 elementwise into Array1, this works because Array1 and Array2 have the same length. But when you try to do

Array1[Array1 .== 0] .= Array2

You are telling to put every element of Array2 into a subset of elements in Array1 (the ones that satisfy your condition). This fail because the arrays are not of the same length. If you instead do

Array1[Array1 .== 0] .= Array2[Array1 .== 0] 

You are now telling "copy all the elements of Array2 in the indices where Array1 satisfy the condition, into the same place in Array1". These two now are of the same length.

Note, however, that in julia for loops are fast, so you will be fine if you use them.

like image 192
aramirezreyes Avatar answered Oct 16 '22 18:10

aramirezreyes


Instead of indexing, you could also broadcast a function over the values. Here I've used 100*Array2 for the replacement values just so you can see which were changed, and @. is equivalent to writing out Array1 .= ifelse.(Array1 .== 0, 100 .* etc. but ensures you won't miss a dot.

julia> @. Array1 = ifelse(Array1==0, 100*Array2, Array1)
9-element Vector{Int64}:
 100
   2
   4
   2
   5
 600
 700
   2
   5

This is likely to be more efficient, as each Array1 .== 0 makes a boolean array, and Array2[Array1 .== 0] makes a temporary copy of this data.

like image 33
mcabbott Avatar answered Oct 16 '22 17:10

mcabbott