Reputation: 5444
I have a numpy
array in python called my_values
of size 5x5 and a numpy
vector which contains boolean values with size 1x90 (5 False, 85 True) naned cols_indexes. I want to expand my initial array my_values
with zeros in the positions indexes of the cols_indexes that are equal to False
. Thus in the end my transformed matrix my_values
should be of size 5x90 (with 85 new columns filled with zero). A simple example that uses an array instead of a vector of Boolean's is:
def insert_one_per_row(arr, mask, putval):
mask_ext = np.column_stack((mask, np.zeros((len(mask), 1), dtype=bool)))
out = np.empty(mask_ext.shape, dtype=arr.dtype)
out[~mask_ext] = arr.ravel()
out[mask_ext] = putval
return out
y = np.arange(25).reshape(5, 5)
x = np.array([[False, True, False, False, False],
[False, True, False, False, False],
[False, True, False, False, False],
[False, True, False, False, False],
[False, True, False, False, False]], dtype=bool)
arr = insert_one_per_row(y, x, putval=0)
This example works with an array of Boolean's. However in my case x
is a vector instead of an array. x
contains True
for a new column in the position that I need to add and False
for an existing one in the position of the final array. How can I insert the new columns using the vector x
instead of the matrix x
?
Upvotes: 1
Views: 121
Reputation: 231335
Your inputs - adjusted to work:
In [73]: y = np.arange(1,21).reshape(5, 4)
...: x = np.array([[False, True, False, False, False],
...: [False, True, False, False, False],
...: [False, True, False, False, False],
...: [False, True, False, False, False],
...: [False, True, False, False, False]], dtype=bool)
...:
The whole array masking, roughly what your function does
In [74]: res = np.full(x.shape, 0) # assign the putval on creation
In [75]: res[~x] = y.ravel()
In [76]: res
Out[76]:
array([[ 1, 0, 2, 3, 4],
[ 5, 0, 6, 7, 8],
[ 9, 0, 10, 11, 12],
[13, 0, 14, 15, 16],
[17, 0, 18, 19, 20]])
We can use where
to get the column indices from a 1d mask, here a row of x
:
In [77]: res[:, np.where(~x[0,:])[0]]
Out[77]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16],
[17, 18, 19, 20]])
assignment - but don't use ravel since the RHS is (4,5). This indexing doesn't flatten array like the full boolean mask:
In [80]: res[:, np.where(~x[0,:])[0]] = 2*y
In [81]: res
Out[81]:
array([[ 2, 0, 4, 6, 8],
[10, 0, 12, 14, 16],
[18, 0, 20, 22, 24],
[26, 0, 28, 30, 32],
[34, 0, 36, 38, 40]])
Upvotes: 1