scipy fftconvolve声明输入参数不具有相同的维度。我在解析什么?

时间:2015-06-13 13:45:06

标签: python scipy

我正在尝试使用 scipy.signal 中的 fftconvolve 创建一个类,以便在类实例的方法中使用高斯卷积一些数据。但是每次创建一个实例并调用方法 enlarge_smooth (在按下右箭头键时发生),我从 fftconvolve 中得到一个错误: ValueError:in1 and in2应具有相同的维度。当行def fftconvolve(in1, in2, mode="full"):评估为 True 时,会在函数elif not in1.ndim == in2.ndim:中发生这种情况。但是,我的行print vals.ndim == gs.ndim在调用 fftconvolve 之前打印 True ,而 vals gs 都有尺寸(101,)。所以如果我没有解析 vals gs fftconvolve 我在解析什么?为什么它不起作用?

class Smoother(object):
    import sys
    sys.path.append("/DATA/Pythonfunktioner")
    from scipy.signal import fftconvolve
    import pyximport; pyximport.install()
    from fitting6 import gs_smooth1
    """
    This class allows the user to smooth any function of one variable with a gaussian using fftconvolve while looking at the smoothed function. The smoothing parameter is changed with the arrow keys and finally chosen with enter.
    """

    def __init__(self, data):
        self.data = data
        self.sigma = 1 #smallest possible sigma for this smoothing
        self.arr = np.arange(len(self.data.get_ydata()), dtype='float64') - len(self.data.get_ydata())/2
        self.stack = [data]
        self.line = data
        self.active = True

    def connect(self):
        self.cidkpress = self.data.figure.canvas.mpl_connect('key_press_event', self.key)

    def key(self, event):
        if event.key == 'right':
            self.enlarge_smooth()
        elif event.key == 'left':
            self.lower_smooth()
        elif event.key == 'enter':
            self.term(event)

    def enlarge_smooth(self):
        if 0: #Check if larger smooth is already in stack
            pass#set larger smooth as current
        else:
            gs = self.gs_smooth1(self.arr.copy(), self.sigma) #Gaussian core centered at 0
            vals = self.data.get_ydata().copy()
            print vals.ndim == gs.ndim
            print vals.ndim, type(vals), vals.dtype
            print gs.ndim, type(gs), gs.dtype
#            print vals, type(vals), vals.dtype
#            print gs, type(gs), gs.dtype
            newsmooth = self.fftconvolve(vals, gs)
            self.line = Line2D(self.data.get_xdata(), newsmooth)
            self.stack.append(self.line)

    def lower_smooth(self):
        if 1: #Check if current smooth is lowest possible
            print "Cannot smooth less. Least smooth already active."
        else:
            pass#Set lesser smooth as current

    def term(self, event):
        self.active = False
        self.disconnect()

    def disconnect(self):
        self.data.figure.canvas.mpl_disconnect(self.cidkpress)

我还尝试解析vals[0]gs[0]以检查我是否会解析两个长度为101的列表。事实证明我只会解析两个标量,而ftconvolve`会退出错误: TypeError:不支持的操作数类型*:'Smoother'和'float'

看起来我正在解析类本身的实例。我只是看不出来。

如果通过调用以下函数来帮助我测试我的课程

def smoothBF(datalist):
    from matplotlib import pyplot as plt
    for i in xrange(len(datalist)):
        fig, axs = plt.subplots(nrows=1, ncols=1)
        data, = axs.plot(datalist[i][0], datalist[i][1])
        smoother = Smoother(data)
        smoother.connect()
        while smoother.active:
            plt.pause(0.1)
        #Return current result
        plt.close(fig)

其中 datalist 是仅包含元组(np.arange(101), np.random.random(101))

的列表

更新:它似乎与在类定义中导入fftconvolve有关。添加一些 print 语句以获取scipy fftconvolve函数内的维度类型和数量会使 in1 以某种方式成为 Smoother 类型。但是当我在模块顶部写from scipy.signal import fftconvolve而不是在类定义中并且调用newsmooth = fftconvolve(vals, gs)而不是newsmooth = self.fftconvolve(vals, gs)时,它也会产生不同的结果。然后我收到错误消息 AttributeError:'numpy.ndarray'对象没有来自 fftconvolve 的属性'ndims'

2 个答案:

答案 0 :(得分:0)

以某种方式在类定义中使用from scipy.signal import fftconvolve使得对它的任何调用都会解析类本身的实例。在类定义之外进行导入并修改 fftconvolve 编辑中的拼写错误(如我的问题更新中所述),这使得解析正确并且代码运行。

答案 1 :(得分:0)

在类定义中导入fftconvolve的“技巧”最终会引起你的兴趣。除非您没有向我们展示您在其他地方定义Smooth.fftconvolve的位置。

以下是您现在所拥有的:

class Smooth(object):
    from scipy.signal import fftconvolve

    def enlarge_smooth(self):
        # other stuff
        self.fftconvolve(vals, gs)

当你打电话

s = S()
s.enlarge_smooth()

fftconvolve将被称为

fftconvolve(self, vals, gs)

解决方案很简单:不要做这种诡计。 相反,在类外导入fftconvolve并直接调用函数:

from scipy.signal import fftconvolve

class Smooth(object):

    def enlarge_smooth(self):
        # other stuff
        fftconvolve(vals, gs)