簡體   English   中英

具有多維(或非標量)輸出的Scipy濾波器

[英]Scipy filter with multi-dimensional (or non-scalar) output

是否有類似於ndimagegeneric_filter的過濾器支持向量輸出? 我沒有設法使scipy.ndimage.filters.generic_filter返回超過標量。 取消注釋下面代碼中的行以獲取錯誤: TypeError: only length-1 arrays can be converted to Python scalars

我正在尋找一個處理2D或3D數組的通用過濾器,並在每個點返回一個向量。 因此,輸出將具有一個附加維度。 對於下面的例子,我希望這樣的事情:

m.shape    # (10,10)
res.shape  # (10,10,2)

示例代碼

import numpy as np
from scipy import ndimage

a = np.ones((10, 10)) * np.arange(10)

footprint = np.array([[1,1,1],
                    [1,0,1],
                    [1,1,1]])

def myfunc(x):
    r = sum(x)
    #r = np.array([1,1])  # uncomment this
    return r

res = ndimage.generic_filter(a, myfunc, footprint=footprint)

generic_filter期望myfunc返回一個標量,而不是一個向量。 但是,沒有任何東西阻止myfunc 將信息添加到例如作為額外參數傳遞給myfunc的列表中。

我們可以通過重新整理此列表來生成矢量值數組,而不是使用generic_filter返回的數組。


例如,

import numpy as np
from scipy import ndimage

a = np.ones((10, 10)) * np.arange(10)

footprint = np.array([[1,1,1],
                      [1,0,1],
                      [1,1,1]])

ndim = 2
def myfunc(x, out):
    r = np.arange(ndim, dtype='float64')
    out.extend(r)
    return 0

result = []
ndimage.generic_filter(
    a, myfunc, footprint=footprint, extra_arguments=(result,))
result = np.array(result).reshape(a.shape+(ndim,))

我想我得到了你所要求的,但我不完全確定ndimage.generic_filter是如何工作的(源代碼有多深奧!)。

這里只是一個簡單的包裝函數。 這個函數將接受一個數組, ndimage.generic_filter需要的所有參數。 函數返回一個數組,其中前一個數組的每個元素現在由一個形狀為(2,)的數組表示,函數的結果存儲為該數組的第二個元素。

def generic_expand_filter(inarr, func, **kwargs):
    shape = inarr.shape
    res = np.empty((  shape+(2,) ))
    temp = ndimage.generic_filter(inarr, func, **kwargs)
    for row in range(shape[0]):
        for val in range(shape[1]):
            res[row][val][0] = inarr[row][val]
            res[row][val][1] = temp[row][val]
    return res

輸出,其中res表示generic_filter ,res2表示generic_expand_filter ,此函數是:

>>> a.shape #same as res.shape
(10, 10)
>>> res2.shape
(10, 10, 2)

>>> a[0]
array([ 0.,  1.,  2.,  3.,  4.,  5.,  6.,  7.,  8.,  9.])
>>> res[0]
array([  3.,   8.,  16.,  24.,  32.,  40.,  48.,  56.,  64.,  69.])
>>> print(*res2[0], sep=", ") #this is just to avoid the vertical default output
[ 0.  3.], [ 1.  8.], [  2.  16.], [  3.  24.], [  4.  32.], [  5.  40.], [  6.  48.], [  7.  56.], [  8.  64.], [  9.  69.]

>>> a[0][0]
0.0
>>> res[0][0]
3.0
>>> res2[0][0]
array([ 0.,  3.])

當然,您可能不想保存舊數組,而是將兩個字段都作為新結果。 除了我不知道你究竟想到了什么,如果你想要存儲的兩個值是不相關的,只需添加一個temp2func2並調用另一個帶有相同**kwargs generic_filter並將其存儲為第一個值。

但是,如果你想要一個使用多個inarr元素計算的實際矢量,意味着兩個新創建的字段不是獨立的,那么你只需要編寫一種函數,一個接收數組的函數, idxidy索引並返回一個元組\\ list \\ array值,然后您可以將其解壓縮並分配給結果。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM