Home > Enterprise >  is there a way in python that can I merge two arrays (1d/2d/3d) and replacing specific elements
is there a way in python that can I merge two arrays (1d/2d/3d) and replacing specific elements

Time:10-06

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]]])
  • Related