[英]Scipy filter with multi-dimensional (or non-scalar) output
Is there a filter similar to ndimage
's generic_filter that supports vector output? 是否有类似于
ndimage
的generic_filter的过滤器支持向量输出? I did not manage to make scipy.ndimage.filters.generic_filter
return more than a scalar. 我没有设法使
scipy.ndimage.filters.generic_filter
返回超过标量。 Uncomment the line in the code below to get the error: TypeError: only length-1 arrays can be converted to Python scalars
. 取消注释下面代码中的行以获取错误:
TypeError: only length-1 arrays can be converted to Python scalars
。
I'm looking for a generic filter that process 2D or 3D arrays and returns a vector at each point. 我正在寻找一个处理2D或3D数组的通用过滤器,并在每个点返回一个向量。 Thus the output would have one added dimension.
因此,输出将具有一个附加维度。 For the example below I'd expect something like this:
对于下面的例子,我希望这样的事情:
m.shape # (10,10)
res.shape # (10,10,2)
Example Code 示例代码
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)
The generic_filter
expects myfunc
to return a scalar, never a vector. generic_filter
期望myfunc
返回一个标量,而不是一个向量。 However, there is nothing that precludes myfunc
from also adding information to, say, a list which is passed to myfunc
as an extra argument. 但是,没有任何东西阻止
myfunc
也将信息添加到例如作为额外参数传递给myfunc
的列表中。
Instead of using the array returned by generic_filter
, we can generate our vector-valued array by reshaping this list. 我们可以通过重新整理此列表来生成矢量值数组,而不是使用
generic_filter
返回的数组。
For example, 例如,
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,))
I think I get what you're asking, but I'm not completely sure how does the ndimage.generic_filter
work (how abstruse is the source!). 我想我得到了你所要求的,但我不完全确定
ndimage.generic_filter
是如何工作的(源代码有多深奥!)。
Here's just a simple wrapper function. 这里只是一个简单的包装函数。 This function will take in an array, all the parameters
ndimage.generic_filter
needs. 这个函数将接受一个数组,
ndimage.generic_filter
需要的所有参数。 Function returns an array where each element of the former array is now represented by an array with shape (2,), result of the function is stored as the second element of that array. 函数返回一个数组,其中前一个数组的每个元素现在由一个形状为(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
Output, where res
denotes just the generic_filter
and res2 denotes generic_expand_filter
, of this function is: 输出,其中
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.])
Of course you probably don't want to save the old array, but instead have both fields as new results. 当然,您可能不想保存旧数组,而是将两个字段都作为新结果。 Except I don't know what exactly you had in mind, if the two values you want stored are unrelated, just add a
temp2
and func2
and call another generic_filter
with the same **kwargs
and store that as the first value. 除了我不知道你究竟想到了什么,如果你想要存储的两个值是不相关的,只需添加一个
temp2
和func2
并调用另一个带有相同**kwargs
generic_filter
并将其存储为第一个值。
However if you want an actual vector quantity that is calculated using multiple inarr
elements, meaning that the two new created fields aren't independent, you are just going to have to write that kind of a function, one that takes in an array, idx
, idy
indices and returns a tuple\\list\\array value which you can then unpack and assign to the result. 但是,如果你想要一个使用多个
inarr
元素计算的实际矢量,意味着两个新创建的字段不是独立的,那么你只需要编写一种函数,一个接收数组的函数, idx
, idy
索引并返回一个元组\\ list \\ array值,然后您可以将其解压缩并分配给结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.