6

I'm looking to quickly (hopefully without a for loop) generate a Numpy array of the form:

array([a,a,a,a,0,0,0,0,0,b,b,b,0,0,0, c,c,0,0....])

Where a, b, c and other values are repeated at different points for different ranges. I'm really thinking of something like this:

import numpy as np
a = np.zeros(100)
a[0:3,9:11,15:16] = np.array([a,b,c])

Which obviously doesn't work. Any suggestions?

Edit (jterrace answered the original question): The data is coming in the form of an N*M Numpy array. Each row is mostly zeros, occasionally interspersed by sequences of non-zero numbers. I want to replace all elements of each such sequence with the last value of the sequence. I'll take any fast method to do this! Using where and diff a few times, we can get the start and stop indices of each run.

raw_data = array([.....][....])
starts = array([0,0,0,1,1,1,1...][3, 9, 32, 7, 22, 45, 57,....])
stops = array([0,0,0,1,1,1,1...][5, 12, 50, 10, 30, 51, 65,....])
last_values = raw_data[stops]
length_to_repeat = stops[1]-starts[1]

Note that starts[0] and stops[0] are the same information (which row the run is occurring on). At this point, since the only route I know of is what jterrace suggest, we'll need to go through some contortions to get similar start/stop positions for the zeros, then interleave the zero start/stop with the values start/stops, and interleave the number 0 with the last_values array. Then we loop over each row, doing something like:

for i in range(N)
    values_in_this_row = where(starts[0]==i)[0]
    output[i] = numpy.repeat(last_values[values_in_this_row], length_to_repeat[values_in_this_row])

Does that make sense, or should I explain some more?

1
  • What's the form of the input? Tuples of the form (start, stop, value) ? Commented Aug 16, 2011 at 22:29

2 Answers 2

4

If you have the values and repeat counts fully specified, you can do it this way:

>>> import numpy
>>> values = numpy.array([1,0,2,0,3,0])
>>> counts = numpy.array([4,5,3,3,2,2])
>>> numpy.repeat(values, counts)
array([1, 1, 1, 1, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 3, 3, 0, 0])
Sign up to request clarification or add additional context in comments.

2 Comments

This does exactly what I was looking for. Thanks! Now, would there be a way to push it one step further, to make: array([[a,a,a,a,0,0,0,0,0,b,b,b,...], [0,0,0, c,c,0,0, d d,d,....]]) As you imagined, the data is coming in with the form (start, stop, value). However, it's really in the form (start, stop, value, channel). Looping over each channel is probably acceptable, but if it can be pushed further, why not? :-) Numpy.repeat doesn't seem to be able to do that.
Not really sure what you mean. If you could amend your question with the exact example input and output, that would be helpful.
0

you can use numpy.r_:

>>> np.r_[[a]*4,[b]*3,[c]*2]
array([1, 1, 1, 1, 2, 2, 2, 3, 3])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.