Simple case-
I have two arrays:
x1 = np.arange(1,10) and x2 = np.array([0,0,4,0,0,5,0,0,0])
I would like to merge or combine these two arrays such that the 0 in x2 will be replaced with values in x1 and the non-zero elements of x2 remains. NumPy.union1d seems to do this union. But I don't want it sorted/ordered.
Then
Actual case-
I would then like to perform this on multi-dimensional arrays, eg: x.shape=(xx,yy,zz). Both array objects will have the same shape. x.shape = y.shape
Is this possible or should I try something with masked arrays NumPy.ma?
---------------------------Example-----------------------------
k_angle = khan(_angle)
e_angle = emss(_angle)
_angle.shape = (3647, 16)
e_angle.shape = (2394, 3647, 16)
k_angle.shape = (2394, 3647, 16)
_angle contains a list of values 0 - 180 degrees, if angle < 5 it should only use one function khan anything else is emss function.
Any value larger than 5 for khan becomes 0. While emss works for all values.
Attempt 1: I tried splitting the angle values but recombining them proved tricky
khan = bm.Khans_beam_model(freq=f, theta=None)
emss = bm.emss_beam_model(f=f)
test = np.array([[0,1,2], [3,4,5], [6,7,8], [9,10,11]])
gt_idx = test > 5
le_idx = test <= 5
# then update the array
test[gt_idx] = khan(test[gt_idx])
test[le_idx] = emss(test[le_idx])
But this gets an error TypeError: NumPy boolean array indexing assignment requires a 0 or 1-dimensional input, input has 2 dimensions
khan and emss are `lambda' functions
So I thought it would easier to execute khan and emss and then merge after the fact.
I applied the simple case above to help ease the question.
CodePudding user response:
The np.where(boolean_mask, value_if_true, value_otherwise) function should be sufficient as long as x1 and x2 are the same shape.
Here, you could use np.where(x2, x2, x1) where the condition is simply x2, which means that truthy values (non-zero) will be preserved and falsy values will be replaced by the corresponding values in x1. In general, any boolean mask will work as a condition, and it is better to be explicit here: np.where(x2 == 0, x1, x2).
1D
In [1]: import numpy as np
In [2]: x1 = np.arange(1, 10)
In [3]: x2 = np.array([0,0,4,0,0,5,0,0,0])
In [4]: np.where(x2 == 0, x1, x2)
Out[4]: array([1, 2, 4, 4, 5, 5, 7, 8, 9])
2D
In [5]: x1 = x1.reshape(3, 3)
In [6]: x2 = x2.reshape(3, 3)
In [7]: x1
Out[7]:
array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
In [8]: x2
Out[8]:
array([[0, 0, 4],
[0, 0, 5],
[0, 0, 0]])
In [9]: np.where(x2 == 0, x1, x2)
Out[9]:
array([[1, 2, 4],
[4, 5, 5],
[7, 8, 9]])
3D
In [10]: x1 = np.random.randint(1, 9, (2, 3, 3))
In [11]: x2 = np.random.choice((0, 0, 0, 0, 0, 0, 0, 0, 99), (2, 3, 3))
In [12]: x1
Out[12]:
array([[[3, 7, 4],
[1, 4, 3],
[7, 4, 3]],
[[5, 7, 1],
[5, 7, 6],
[1, 8, 8]]])
In [13]: x2
Out[13]:
array([[[ 0, 99, 99],
[ 0, 99, 0],
[ 0, 99, 0]],
[[99, 0, 0],
[ 0, 0, 99],
[ 0, 99, 0]]])
In [14]: np.where(x2 == 0, x1, x2)
Out[14]:
array([[[ 3, 99, 99],
[ 1, 99, 3],
[ 7, 99, 3]],
[[99, 7, 1],
[ 5, 7, 99],
[ 1, 99, 8]]])
