当前位置: 首页 > 面试题库 >

我如何在类似于Matlab的blkproc(blockproc)函数的块中高效处理numpy数组

束高雅
2023-03-14
问题内容

我正在寻找一种有效的方法,用于将图像有效地划分为较小的区域,分别处理每个区域,然后将每个过程的结果重新组合为一个已处理的图像。Matlab为此提供了一个名为blkproc的工具(blockproc在较新的Matlab版本中被替换)。

在理想情况下,函数或类也将支持输入矩阵中各部分之间的重叠。在Matlab帮助中,blkproc定义为:

B = blkproc(A,[mn],[mborder nborder],fun,…)

  • A是您的输入矩阵,
  • [mn]是块大小
  • [mborder,nborder]是边界区域的大小(可选)
  • fun是应用于每个块的功能

我已经拼凑出一个方法,但是它让我感到笨拙,我敢打赌,还有更好的方法。冒着我自己的窘境,这是我的代码:

import numpy as np

def segmented_process(M, blk_size=(16,16), overlap=(0,0), fun=None):
    rows = []
    for i in range(0, M.shape[0], blk_size[0]):
        cols = []
        for j in range(0, M.shape[1], blk_size[1]):
            cols.append(fun(M[i:i+blk_size[0], j:j+blk_size[1]]))
        rows.append(np.concatenate(cols, axis=1))
    return np.concatenate(rows, axis=0)

R = np.random.rand(128,128)
passthrough = lambda(x):x
Rprime = segmented_process(R, blk_size=(16,16), 
                           overlap=(0,0), 
                           fun=passthrough)

np.all(R==Rprime)

问题答案:

以下是使用块的另一种(无循环)方法的示例:

import numpy as np
from numpy.lib.stride_tricks import as_strided as ast

A= np.arange(36).reshape(6, 6)
print A
#[[ 0  1  2  3  4  5]
# [ 6  7  8  9 10 11]
# ...
# [30 31 32 33 34 35]]

# 2x2 block view
B= ast(A, shape= (3, 3, 2, 2), strides= (48, 8, 24, 4))
print B[1, 1]
#[[14 15]
# [20 21]]

# for preserving original shape
B[:, :]= np.dot(B[:, :], np.array([[0, 1], [1, 0]]))
print A
#[[ 1  0  3  2  5  4]
# [ 7  6  9  8 11 10]
# ...
# [31 30 33 32 35 34]]
print B[1, 1]
#[[15 14]
# [21 20]]

# for reducing shape, processing in 3D is enough
C= B.reshape(3, 3, -1)
print C.sum(-1)
#[[ 14  22  30]
# [ 62  70  78]
# [110 118 126]]

因此,仅尝试简单地将matlab功能复制到numpy并不是所有最佳方式。有时需要“脱帽而出”的思维。

注意
通常,基于跨步技巧的实现 可能会
(但不一定需要)遭受一些性能损失。因此,请做好准备以各种方式衡量您的表现。无论如何,明智的做法是先检查所需的功能(或足够相似,以便轻松适应)是否已在numpy或中实现scipy

更新
请注意,这里没有magic涉及任何实际内容strides,因此我将提供一个简单的函数来获取block_view任何合适的2Dnumpy数组。所以我们开始:

from numpy.lib.stride_tricks import as_strided as ast

def block_view(A, block= (3, 3)):
    """Provide a 2D block view to 2D array. No error checking made.
    Therefore meaningful (as implemented) only for blocks strictly
    compatible with the shape of A."""
    # simple shape and strides computations may seem at first strange
    # unless one is able to recognize the 'tuple additions' involved ;-)
    shape= (A.shape[0]/ block[0], A.shape[1]/ block[1])+ block
    strides= (block[0]* A.strides[0], block[1]* A.strides[1])+ A.strides
    return ast(A, shape= shape, strides= strides)

if __name__ == '__main__':
    from numpy import arange
    A= arange(144).reshape(12, 12)
    print block_view(A)[0, 0]
    #[[ 0  1  2]
    # [12 13 14]
    # [24 25 26]]
    print block_view(A, (2, 6))[0, 0]
    #[[ 0  1  2  3  4  5]
    # [12 13 14 15 16 17]]
    print block_view(A, (3, 12))[0, 0]
    #[[ 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]]


 类似资料:
  • 问题内容: 我在Matlab中目前具有以下结构的数据 其中item是来自i = 1 .. n的单元格,每个单元格包含多个属性的数据结构,每个属性均具有大小为2,j的矩阵,其中j = 1 .. m。属性的数量不是固定的。 我必须将此数据结构转换为python,但是我对numpy和python列表并不陌生。用numpy / scipy在python中构造此数据的最佳方法是什么? 谢谢。 问题答案: 我

  • 问题内容: 这是在本地处理程序的上下文中。我想运行一个外部程序来获取一些数据。我可以使用popen()或等效函数吗? 问题答案: 然后,您可以使用流读取和写入数据。

  • 本文向大家介绍浅谈Mysql中类似于nvl()函数的ifnull()函数,包括了浅谈Mysql中类似于nvl()函数的ifnull()函数的使用技巧和注意事项,需要的朋友参考一下 IFNULL(expr1,expr2) 如果expr1不是NULL,IFNULL()返回expr1,否则它返回expr2。IFNULL()返回一个数字或字符串值,取决于它被使用的上下文环境。 如果expr1是TRUE(e

  • 问题内容: 我想使用NumPy执行以下MATLAB代码的等效项:。我将如何完成? 问题答案: 对于Matlab用户,这是一个更好(官方)的NumPy链接-恐怕其中的Mathesaurus已经过时了。 的numpy的当量是。 这适用于多个维度,并提供与matlab类似的结果。(Numpy给出了3d输出数组,正如您期望的那样-由于某些原因,matlab提供了2d输出-但内容相同)。 Matlab: 蟒

  • NumPy 提供了许多字符串处理函数,它们被定义在用于处理字符串数组的 numpy.char 这个类中,这些函数的操作对象是 string_ 或者 unicode_ 字符串数组。如下表所示: NumPy处理字符串数组函数 函数名称 描述 add() 对两个数组相应位置的字符串做连接操作。 multiply()  返回多个字符串副本,比如将字符串“ hello”乘以3,则返回字符串“ hello h

  • 问题内容: 我正在寻找一个能够与TSQL的MySQL REGEX函数做相同事情的函数。基本上,我需要我的查询看起来像以下内容: 我目前不希望使用CLR。 有任何想法吗? 问题答案: 此链接是有关通过服务器上的VBScript.Regex库编写正则表达式的文章:http : //www.sqlteam.com/article/regular-expressions-in-t- sql 它通过OLE自