7

是否有类似于支持向量输出ndimagegeneric_filter的过滤器?我没有设法使scipy.ndimage.filters.generic_filterreturn 超过一个标量。取消注释下面代码中的行以获取错误: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)
4

2 回答 2

6

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,))
于 2015-02-28T02:47:43.973 回答
0

我想我明白了你的要求,但我不完全确定它是如何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.])

当然,您可能不想保存旧数组,而是将两个字段都作为新结果。除非我不知道您到底在想什么,如果您要存储的两个值不相关,只需添加一个temp2and并用相同的值func2调用另一个并将其存储为第一个值。generic_filter**kwargs

但是,如果你想要一个使用多个元素计算的实际向量inarr,这意味着两个新创建的字段不是独立的,你只需要编写那种函数,一个接受数组的函数idxidy索引并返回一个 tuple\list\array 值,然后您可以将其解包并分配给结果。

于 2015-02-28T00:13:10.813 回答