Issue
Looking for an efficient (vectorized) way in Numpy or PyTorch to achieve the array z
when given input arrays x
and y
:
1D array x
contains a list of increasing ID's, each of which repeats 1 or more times (not necessarily repeating for the same number of times for each ID). For example, [0 0 0 1 1 2 2 2 2]
1D array y
of 0's and 1's. There is at least one element equal to "1" for each unique ID in x
. For example, [1 1 0 1 1 0 0 1 0]
.
1D output array z
which is equal to y
, but keeping only the first occurrence of "1" in y
per ID in x
. The remaining elements of y
for that ID should be set to "0". So in the example, the result would be [1 0 0 1 0 0 0 1 0]
x: [0 0 0 1 1 2 2 2 2]
y: [1 1 0 1 1 0 0 1 0]
z: [1 0 0 1 0 0 0 1 0]
I feel like there's a quick way to do this in Numpy or PyTorch, but I couldn't figure it out.
Edit: Here's the "slow" version using a while-loop
x = np.array([0, 0, 0, 1, 1, 2, 2, 2, 2])
y = np.array([1, 1, 0, 1, 1, 0, 0, 1, 0])
z = y.copy()
n = z.shape[0]
i = 0
while i < n:
if y[i] == 1:
current_id = x[i]
i += 1
while i < n and x[i] == current_id:
z[i] = 0
i += 1
else:
i += 1
Solution
You could use np.unique
:
unq, ind = np.unique(np.stack((x, y)), axis=1, return_index=True)
ind
now contains the first occurrence of each unique combination of elements. You just need to remove the ones where y
is zero:
keep = unq[1, :] != 0
ind = ind[keep]
Now you can make z
directly:
z = np.zeros_like(y)
z[ind] = 1
Answered By - Mad Physicist
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.