Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I have a vector with indexes and vector with values.

For every index in the indexes vector I need to efficiently produce a row in numpy array of reslts

The row in the results array needs to contain the previous value of the index in values, the indexed value and two next values.

Here is how I do this with a loop:

import numpy as np

indexes = np.array([5,10,12])
values =  np.array([ 0.89643977,  0.50794841,  0.75995795,  0.78029348,  0.83609961,
        0.47534985,  0.17330516,  0.15152753,  0.15504392,  0.10245308,
        0.70428183,  0.36804107,  0.13074141,  0.77377332,  0.11368238,
        0.74711745,  0.89431082,  0.35544423,  0.08592396,  0.28762   ])

result = values[indexes[0] -1:index[0] -1 + 4]
for index in indexes[1:]:
    result = numpy.vstack([result, values[index -1:index -1 + 4]])

print result
[[ 0.83609961  0.47534985  0.17330516  0.15152753]
 [ 0.10245308  0.70428183  0.36804107  0.13074141]
 [ 0.36804107  0.13074141  0.77377332  0.11368238]]

My indexes and values arrays are big and the loop takes too much time. Is there a way to do this with out a loop?

share|improve this question

2 Answers 2

up vote 2 down vote accepted

This will work as long as no index falls out of bounds, and should be much faster:

In [4]: idx = indexes[:, None] + np.arange(-1, 3)

In [5]: values[idx]
Out[5]:
array([[ 0.83609961,  0.47534985,  0.17330516,  0.15152753],
       [ 0.10245308,  0.70428183,  0.36804107,  0.13074141],
       [ 0.36804107,  0.13074141,  0.77377332,  0.11368238]])
share|improve this answer
    
Thank you. Didn't think of that. There will be indexes out of bounds in my data. Do you have any suggestion on how to deal with that? –  Ivelin Mar 28 '14 at 10:06
    
Well, the two obvious options would be to either do np.clip(idx, 0, len(values)-1, out=idx) or idx %= len(values) before actually indexing. The first option will repeat the first or last item for indices out of bounds, the second will wrap around, as if your array was circular and had both ends connected. It depends on what do you want to use it for. –  Jaime Mar 28 '14 at 13:41

Is there any reason why you chose values[index -1:][:4] over values[index -1: index -1 + 4]? Also my guess is you rather want to gather all results in a list and then np.vstack rather that doing it in the loop. Pending better answers, you can thus consider using:

ls_results = [values[index -1:index -1 + 4] for index in indexes]
result = np.vstack(ls_results)
share|improve this answer
    
Yes this is a better way of doing it but you still use loop. My goal is to get the result with out loop –  Ivelin Mar 28 '14 at 9:59
    
Fully agree :). Regarding out of bounds indexes, I guess it should not be too costly to exclude indexes which are out of bound or to too close to the bounds prior to getting each array. If you want to keep those close to bounds (e.g. index 0 or 19 for a 20 elements array, you may consider adding one np.nan at the beginning of values and 2 at the end). –  etna Mar 28 '14 at 10:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.