If I have an array a
with 100 elements that I want to conditionally update. I have the first mask m
which selects elements of a
that will be tried to update. Out of a[m]
(say, 50 elements), I want to update a subset some elements, but leaves others. So the second mask m2
has 50=m.sum()
elements, only some of which are True
.
For completeness, a minimal example:
a = np.random.random(size=100)
m = a > 0
m2 = np.random.random(size=m.sum()) < 0
newvalues = -np.random.randint(size=m2.sum())
Then if I were to do
a[m][m2] = newvalues
This does not change the values of a, because fancy indexing a[m]
makes a copy here. using indices (with where
) has the same behaviour.
Instead, this works:
m12 = m.copy()
m12[m] = m2
a[m12] = newvalues
However, this is verbose and difficult to read.
Is there a more elegant way to update a subset of a subset of an array?
CodePudding user response:
First compute the indices of elements to update:
indices = np.array(range(100))
indices = indices[m1][m2]
then use indices
to update array a
:
a[indices] = newvalue
CodePudding user response:
You can potentially first compute the "final index" of interest and then use those indexes to update. One way to achieve this in a more "numpy" way is to mask the first index array, which is computed based on the first mask array.
final_mask = np.where(m)[0][m2]
a[final_mask] = newvalues