Scipy 具有多维(或非标量)输出的过滤器
Scipy filter with multi-dimensional (or non-scalar) output
有没有类似ndimage
的generic_filter的滤镜支持向量输出?我没能使 scipy.ndimage.filters.generic_filter
return 不仅仅是一个标量。取消注释下面代码中的行以获取错误:TypeError: only length-1 arrays can be converted to Python scalars
.
我正在寻找一个处理 2D 或 3D 数组的通用过滤器,return在每个点都有一个向量。因此,输出将增加一个维度。对于下面的示例,我希望是这样的:
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)
我想我明白你的问题了,但我不完全确定 ndimage.generic_filter
是如何工作的(来源多么深奥!)。
这里只是一个简单的包装函数。此函数将接收一个数组,其中包含 ndimage.generic_filter
需要的所有参数。函数 returns 一个数组,其中前一个数组的每个 元素 现在由形状为 (2,) 的 array 表示,结果为该函数存储为该数组的第二个元素。
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.])
当然,您可能不想保存旧数组,而是将两个字段都作为新结果。除了我不知道你到底在想什么,如果你想要存储的两个值不相关,只需添加一个 temp2
和 func2
并调用另一个 generic_filter
相同的 **kwargs
并将其存储为第一个值。
但是,如果您想要使用多个 inarr
元素计算的实际矢量,这意味着两个新创建的字段不是独立的,您只需要编写那种函数,一个接受数组、idx
、idy
索引和 returns 一个 tuple\list\array 值,然后您可以将其解包并分配给结果。
generic_filter
期望 myfunc
到 return 是标量,而不是向量。
但是,没有什么可以阻止 myfunc
也 添加信息
例如,作为额外参数传递给 myfunc
的列表。
我们可以通过重塑此列表来生成向量值数组,而不是使用 return 由 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的滤镜支持向量输出?我没能使 scipy.ndimage.filters.generic_filter
return 不仅仅是一个标量。取消注释下面代码中的行以获取错误:TypeError: only length-1 arrays can be converted to Python scalars
.
我正在寻找一个处理 2D 或 3D 数组的通用过滤器,return在每个点都有一个向量。因此,输出将增加一个维度。对于下面的示例,我希望是这样的:
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)
我想我明白你的问题了,但我不完全确定 ndimage.generic_filter
是如何工作的(来源多么深奥!)。
这里只是一个简单的包装函数。此函数将接收一个数组,其中包含 ndimage.generic_filter
需要的所有参数。函数 returns 一个数组,其中前一个数组的每个 元素 现在由形状为 (2,) 的 array 表示,结果为该函数存储为该数组的第二个元素。
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.])
当然,您可能不想保存旧数组,而是将两个字段都作为新结果。除了我不知道你到底在想什么,如果你想要存储的两个值不相关,只需添加一个 temp2
和 func2
并调用另一个 generic_filter
相同的 **kwargs
并将其存储为第一个值。
但是,如果您想要使用多个 inarr
元素计算的实际矢量,这意味着两个新创建的字段不是独立的,您只需要编写那种函数,一个接受数组、idx
、idy
索引和 returns 一个 tuple\list\array 值,然后您可以将其解包并分配给结果。
generic_filter
期望 myfunc
到 return 是标量,而不是向量。
但是,没有什么可以阻止 myfunc
也 添加信息
例如,作为额外参数传递给 myfunc
的列表。
我们可以通过重塑此列表来生成向量值数组,而不是使用 return 由 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,))