2016-11-21 2 views
9

Я считаю себя опытным пользователем numpy, но им не удалось найти решение для следующей проблемы. Предположим, имеются следующие массивы:Операции с уменьшением числа операций поменьше

# sorted array of times 
t = numpy.cumsum(numpy.random.random(size = 100)) 
# some values associated with the times 
x = numpy.random.random(size=100) 
# some indices into the time/data array 
indices = numpy.cumsum(numpy.random.randint(low = 1, high=10,size = 20)) 
indices = indices[indices <90] # respect size of 100 
if len(indices) % 2: # make number of indices even 
    indices = indices[:-1] 

# select some starting and end indices 
istart = indices[0::2] 
iend = indices[1::2] 

Что теперь я хочу, чтобы уменьшить массив значений x учитывая интервалы, обозначаемые istart и iend. То есть

# e.g. use max reduce, I'll probably also need mean and stdv 
what_i_want = numpy.array([numpy.max(x[is:ie]) for is,ie in zip(istart,iend)]) 

Я уже гугле много, но все, что я смог найти покадрово операции через stride_tricks, который позволяет только для обычных блоков. Я не смог найти решение без выполнения цикла pyhthon :-( В моих массивах реальных приложений намного больше и производительность имеет значения, поэтому я использую numba.jit на данный момент.

Есть ли NumPy функции Я недостающее, который в состоянии сделать это

+0

Будет ли 'x' всегда иметь плавающие числа pt в' [0,1) '? – Divakar

+0

№ 'x' в общем случае является гораздо более сложной структурой массива. –

ответ

7

вы смотрели на ufunc.reduceat с np.maximum, вы можете сделать что-то вроде:

>>> np.maximum.reduceat(x, indices) 

, который дает максимальные значения вдоль срезов x[indices[i]:indices[i+1]]. Для того, чтобы получить то, что вы хотите (x[indices[2i]:indices[2i+1]), вы могли бы сделать

>>> np.maximum.reduceat(x, indices)[::2] 

, если вы не возражаете дополнительные расчеты x[inidices[2i-1]:indices[2i]]. Это дает следующее:

>>> numpy.array([numpy.max(x[ib:ie]) for ib,ie in zip(istart,iend)]) 
array([ 0.60265618, 0.97866485, 0.78869449, 0.79371198, 0.15463711, 
     0.72413702, 0.97669218, 0.86605981]) 

>>> np.maximum.reduceat(x, indices)[::2] 
array([ 0.60265618, 0.97866485, 0.78869449, 0.79371198, 0.15463711, 
     0.72413702, 0.97669218, 0.86605981]) 
+1

Я узнал что-то новое ... thx – piRSquared

+0

Awesome, именно это я и искал. Я могу просто держать все индексы в одном массиве, тогда я не делаю никаких накладных вычислений :) Может быть, я должен улучшить свои навыки работы с Google? –

0

вы можете использовать numpy.r_
как это:

what_i_want = np.array([np.max(x[np.r_[ib:ie]]) for ib,ie in zip(istart,iend)]) 
Смежные вопросы