2013-02-17 2 views
11

Я ищу краткую формулу для численного сверления 2D-массива numpy. По бинингам я имею в виду подсчитать средние значения подматрицы или кумулятивные значения. Напр. x = numpy.arange (16) .resape (4, 4) разделили бы на 4 подматрицы по 2х2 каждый и давали numpy.array ([[2.5.4.5], [10.5, 12.5]]), где 2.5 = numpy. средний ([0,1,4,5]) и т. д.Numpy, восстанавливающий 2D-массив

Как эффективно выполнять такую ​​операцию ... У меня нет никакого идеала, как это сделать ...

Большое спасибо ...

+0

являются подматрицы гарантированно соответствовать именно? у вас есть numpy 1.7. доступно (это просто аккуратно, не нужно)? – seberg

+0

У меня есть numpy 1.8dev, но моя работа получается более старой версии ... – user1187727

ответ

17

Вы можете использовать более высокий размерный вид ваш массива и взять среднее по дополнительным измерениям:

In [12]: a = np.arange(36).reshape(6, 6) 

In [13]: a 
Out[13]: 
array([[ 0, 1, 2, 3, 4, 5], 
     [ 6, 7, 8, 9, 10, 11], 
     [12, 13, 14, 15, 16, 17], 
     [18, 19, 20, 21, 22, 23], 
     [24, 25, 26, 27, 28, 29], 
     [30, 31, 32, 33, 34, 35]]) 

In [14]: a_view = a.reshape(3, 2, 3, 2) 

In [15]: a_view.mean(axis=3).mean(axis=1) 
Out[15]: 
array([[ 3.5, 5.5, 7.5], 
     [ 15.5, 17.5, 19.5], 
     [ 27.5, 29.5, 31.5]]) 

В общем, если вы хотите, мусорные контейнеры формы (a, b) для массива (rows, cols), ваше изменение формы его должен быть .reshape(rows // a, a, cols // b, b). Также обратите внимание, что порядок .mean важен, например. a_view.mean(axis=1).mean(axis=3) поднимет ошибку, потому что a_view.mean(axis=1) имеет только три измерения, хотя a_view.mean(axis=1).mean(axis=2) будет работать нормально, но это затрудняет понимание происходящего.

Как есть, приведенный выше код работает только, если вы можете поместить целое число бункеров внутри массива, то есть, если a делит rows и b делит cols. Есть способы справиться с другими случаями, но тогда вам придется определить поведение, которое вы хотите.

+4

On numpy 1.7. вы можете склеить их вместе в '.mean (axis = (1,3))'! – seberg

+1

Я не знал, что это изменение будет возможно, здорово! К сожалению, среднее упорядочивается зависимым, поэтому, как получить среднее значение для ex. субатрикса 2,2 в вашем примере (я имею в виду угол 0,1,6,7 и т. д.)? – user1187727

+1

@ user1187727 Я не думаю, что я понимаю ваш вопрос, но среднее значение '[[0, 1], [6, 7]]' является элементом '[0, 0]' 'a_view.mean (axis = 3) .mean (ось = 1) '. – Jaime

0

Я предполагаю, что вы только хотите знать, как правило, построить функцию, которая выполняет хорошо, и делает что-то с массивами, так же, как numpy.reshape в вашем примере. Поэтому, если производительность действительно имеет значение, и вы уже используете numpy, вы можете написать свой собственный код C для этого, как это делает numpy. Например, реализация arange полностью в C. Почти все с numpy, которое имеет значение с точки зрения производительности, реализовано в C.

Однако перед этим вы должны попытаться реализовать код на python и посмотреть, достаточно. Попробуйте сделать код Python максимально эффективным. Если он по-прежнему не соответствует вашим потребностям в производительности, перейдите на C-путь.

Вы можете прочитать об этом в docs.

1

См the SciPy Cookbook on rebinning, который обеспечивает этот фрагмент кода:

def rebin(a, *args): 
    '''rebin ndarray data into a smaller ndarray of the same rank whose dimensions 
    are factors of the original dimensions. eg. An array with 6 columns and 4 rows 
    can be reduced to have 6,3,2 or 1 columns and 4,2 or 1 rows. 
    example usages: 
    >>> a=rand(6,4); b=rebin(a,3,2) 
    >>> a=rand(6); b=rebin(a,2) 
    ''' 
    shape = a.shape 
    lenShape = len(shape) 
    factor = asarray(shape)/asarray(args) 
    evList = ['a.reshape('] + \ 
      ['args[%d],factor[%d],'%(i,i) for i in range(lenShape)] + \ 
      [')'] + ['.sum(%d)'%(i+1) for i in range(lenShape)] + \ 
      ['/factor[%d]'%i for i in range(lenShape)] 
    print ''.join(evList) 
    return eval(''.join(evList)) 
Смежные вопросы