scipy.ndimage.generic_filter返回类型错误
问题描述:
我正在使用scipy.ndimage.generic_filter
来计算数组的局部模态值。我正在比较两种方法来查看哪种方法更快(因为第一种方法非常慢)。我的第一个方法是;scipy.ndimage.generic_filter返回类型错误
import numpy as np
import scipy.stats as stats
import scipy.ndimage
def modal(arr):
return stats.mode(arr, axis=None)[0][0]
x = np.random.randint(0, 100, size=(10, 10))
scipy.ndimage.filters.generic_filter(x, modal, size=3)
我的第二种方法是;
def modal(arr):
return np.argmax(np.bincount(arr.flatten()))
x = np.random.randint(0, 100, size=(10, 10))
scipy.ndimage.filters.generic_filter(x, modal, size=3)
但与第二种方法我得到这个:
TypeError Traceback (most recent call last)
<ipython-input-122-2e9030c57d71> in <module>()
1 #%timeit -n 5 -r 1
----> 2 scipy.ndimage.filters.generic_filter(x, modal, size=3)
C:\Python27\ArcGIS10.2\lib\site-packages\scipy\ndimage\filters.pyc in generic_filter(input, function, size, footprint, output, mode, cval, origin, extra_arguments, extra_keywords)
1161 mode = _ni_support._extend_mode_to_code(mode)
1162 _nd_image.generic_filter(input, function, footprint, output, mode,
-> 1163 cval, origins, extra_arguments, extra_keywords)
1164 return return_value
<ipython-input-118-86ea9b03ed30> in modal(arr)
1 def modal(arr):
----> 2 return np.argmax(np.bincount(arr.flatten()))
3 return stats.mode(arr, axis=None)[0][0]
TypeError: array cannot be safely cast to required type
当我运行此:
stats.mode(x, axis=None)[0][0] == np.argmax(np.bincount(x.flatten()))
它返回True
为什么generic_filter
抛出类型错误当使用numpy.bincount
方法而不是时方法返回值是否相同?
我在Windows 7上使用Python 2.7.3,Numpy 1.6.1和Scipy 0.14.0(我坚持使用这个版本的Numpy和Python,因为这是ESRI ArcGIS附带的)。我尝试安装scikit-image来计算模态过滤器,但是我在安装时遇到了其他错误,并认为解决这个问题更简单!
答
您可以通过将打印语句在modal
调查此错误:
def modal(arr):
print(arr)
return np.argmax(np.bincount(arr.flatten()))
你会看到输出如下
[ 92. 92. 31. 92. 92. 31. 87. 87. 18.]
这表明arr
包含浮动,而不是整数。 np.bincount
的文档声明其第一个参数必须是非负整数的一维数组。
因此,您可以使用astype('int64')
将浮点数作为整数来避免错误。
import numpy as np
import scipy.stats as stats
import scipy.ndimage
def modal(arr):
return stats.mode(arr, axis=None)[0][0]
def modal2(arr):
count = np.bincount(arr.astype('int64'))
return np.argmax(count)
x = np.random.randint(0, 100, size=(10, 10))
out = np.empty_like(x, dtype='float')
scipy.ndimage.filters.generic_filter(x, modal, size=3, output=out)
print(out)
scipy.ndimage.filters.generic_filter(x, modal2, size=3, output=out)
print(out)
PS。由于arr
已经是一维的,因此可以删除对flatten
的呼叫。