0

Say I have a numpy array

import numpy as np

arr = np.zeros(20)

arr[::4] = func = np.arange(5) # Excuse the setup hack

print(arr)

i.e.

[0. 0. 0. 0. 1. 0. 0. 0. 2. 0. 0. 0. 3. 0. 0. 0. 4. 0. 0. 0.] ,

How can I right-pad the zeroes in the array without a for-loop to give the following?

arr_expected = np.array([0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4])

I should add that the stride length is irregular/arbitrary - NOT every 4 as in the example.

Here is a second example:

import numpy as np
arr = np.zeros(20)
arr[2]=4
arr[9]=3
arr[18]=101
print(arr)

gives:

[ 0. 0. 4. 0. 0. 0. 0. 0. 0. 3. 0. 0. 0. 0. 0. 0. 0. 0. 101. 0.] ,

with the expected output being

arr_expected = np.array([0,0,4,4,4,4,4,4,4,3,3,3,3,3,3,3,3,3,101,101])

Note that this is not a cumulative sum (although, in this case, func is a cumulative sum but only at certain indices in an original array). I have thought about impulses and transfer functions, uneven square waves, interpolation, sliding masks.....

PS The zeros could be any other pad value - np.nan etc. or even an arbitrary array. The point is to fill in the gaps with the values at predefined indices.

Huge thanks as ever

2
  • Why the downvote? Also a comment - which came across as rude - asking for a second example, which I then added, but which ordered me "not to explain"... There was I thinking the question box was a free-form one..... Commented Apr 7, 2022 at 15:07
  • @QuangHoang This is a duplicate but for the fact that my case is 1D not 2D (which I think is a sufficiently-simpler case that might warrant a hopefully-simpler solution)! If others vote to close this one I will do the same. Thanks for the spot, much appreciated! Commented Apr 7, 2022 at 15:22

1 Answer 1

1

At first, we append a value bigger than the maximum of values in the array to get number of repeatation correctly. Furthermore, for doing so, we need to preserve the order of magnitudes in the array, which can be achieved by argsort:

arr = np.append(arr, max(arr) + 1)
unique, inds = np.unique(arr, return_index=True)
sort_ = inds[:-1].argsort()
inds = np.sort(inds)
diff = np.diff(inds)
result = np.repeat(unique[:-1][sort_], diff)

This code get the true result:

[  0   0   4   4   4   4   4   4   4   3   3   3   3   3   3   3   3   3 101 101]
Sign up to request clarification or add additional context in comments.

2 Comments

anything related to np.unique is probably not correct, e.g. arr = [0,2,0,1,0,2,0,0].
@QuangHoang, I agree. This answer is based on the example that the OP provided in which the nonzero values in the array are unique (not repeated). If values could be repeated, there are useful answers in the provided link in this regard.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.