Numpy, восстанавливающий 2D-массив
Я ищу краткую формулировку для численного бинания массива 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]) и т.д.
Как эффективно выполнять такую операцию... У меня нет никакого идеала, как это сделать...
Большое спасибо...
Ответы
Ответ 1
Вы можете использовать более высокий размерный вид вашего массива и принимать среднее значение по дополнительным размерам:
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
. Есть способы справиться с другими случаями, но вам нужно будет определить поведение, которое вы хотите, затем.
Ответ 2
Смотрите кулинарная книга SciPy при обновлении, которая предоставляет этот фрагмент:
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))
Ответ 3
Я предполагаю, что вы только хотите знать, как вообще построить функцию, которая хорошо работает и что-то делает с массивами, точно так же, как numpy.reshape
в вашем примере. Поэтому, если производительность действительно имеет значение, и вы уже используете numpy, вы можете написать свой собственный код C для этого, как это делает numpy. Например, реализация arange полностью в C. Почти все с numpy, что имеет значение с точки зрения производительности, реализовано в C.
Однако, прежде чем делать это, вы должны попытаться реализовать код в python и посмотреть, достаточно ли производительность. Попробуйте сделать код Python максимально эффективным. Если он по-прежнему не соответствует вашим потребностям в производительности, перейдите на путь C.
Вы можете прочитать об этом в docs.