Python 通过求和降低阵列的分辨率

Python 通过求和降低阵列的分辨率,python,numpy,Python,Numpy,如果我有这样一个数组: a = np.array([[ 1, 2, 3, 4], [ 5 ,6, 7, 8], [ 9,10,11,12], [13,14,15,16]]) 我想“改变分辨率”,最后得到一个更小的数组(比如2行乘2列,或者2行乘4列,等等)。我希望通过求和来改变决议。我需要这个来处理大型数组,较小数组的行数和列数总是较大数组的一个因素 将上述数组减少为2乘2数组将导致(这正是我想要的): 我有一

如果我有这样一个数组:

a = np.array([[ 1, 2, 3, 4],
              [ 5 ,6, 7, 8],
              [ 9,10,11,12],
              [13,14,15,16]])
我想“改变分辨率”,最后得到一个更小的数组(比如2行乘2列,或者2行乘4列,等等)。我希望通过求和来改变决议。我需要这个来处理大型数组,较小数组的行数和列数总是较大数组的一个因素

将上述数组减少为2乘2数组将导致(这正是我想要的):

我有一个很好的函数:

import numpy as np

def shrink(data, rows, cols):
    shrunk = np.zeros((rows,cols))
    for i in xrange(0,rows):
        for j in xrange(0,cols):
            row_sp = data.shape[0]/rows
            col_sp = data.shape[1]/cols
            zz = data[i*row_sp : i*row_sp + row_sp, j*col_sp : j*col_sp + col_sp]
            shrunk[i,j] = np.sum(zz)
    return shrunk

print shrink(a,2,2)
print shrink(a,2,1)
#correct output:
[[ 14.  22.]
 [ 46.  54.]]
[[  36.]
 [ 100.]]
我看了很久书,但似乎找不到任何有用的东西

有没有一种更快的方法可以做到这一点,而不需要循环

我相信没有这些可怕的循环,有更好/更聪明的方法

以下是避免显式循环遍历
数据的每个元素的一种方法:

def shrink(data, rows, cols):
  row_sp = a.shape[0] / rows
  col_sp = a.shape[1] / cols
  tmp = np.sum(data[i::row_sp] for i in  xrange(row_sp))
  return np.sum(tmp[:,i::col_sp] for i in xrange(col_sp))
在我的机器上,这比您的版本快约30%(对于
收缩(a,2,2)
)。

以您的示例:

a.reshape(2,2,2,2).sum(axis=1).sum(axis=2)
返回:

array([[14, 22],
       [46, 54]])
现在让我们创建一个通用函数

def shrink(data, rows, cols):
    return data.reshape(rows, data.shape[0]/rows, cols, data.shape[1]/cols).sum(axis=1).sum(axis=2)
适用于您的示例:

In [19]: shrink(a, 2,2)
Out[19]: 
array([[14, 22],
       [46, 54]])

In [20]: shrink(a, 2,1)
Out[20]: 
array([[ 36],
       [100]])

“如果效果很好,你的问题是什么?”Niek de Klein编辑澄清。我在寻找一种更快的方法来实现这一点。想要做这类事情的人倾向于使用
itertools
模块,这可能值得一看。这个问题可能会在这里找到更好的答案,这是令人惊讶的“Numpythonic”。@eumiro你在函数定义上犯了一个小错误,您使用
a
而不是
data
+1非常感谢,这是一种很酷的方法,但eumiro成功地做到了这一点。
In [19]: shrink(a, 2,2)
Out[19]: 
array([[14, 22],
       [46, 54]])

In [20]: shrink(a, 2,1)
Out[20]: 
array([[ 36],
       [100]])