np.roll vs scipy.interpolation.shift——整数移位值的差异

np.roll vs scipy.interpolation.shift--discrepancy for integer shift values

我写了一些代码来移动数组,并试图使用 scipy.ndimage 中的 "shift" 函数将其概括为处理非整数移位。数据是循环的,因此结果应该环绕,就像 np.roll 命令所做的那样。

但是,scipy.ndimage.shift 似乎没有正确包装整数移位。以下代码片段显示了差异:

import numpy as np
import scipy.ndimage as sciim
import matplotlib.pyplot as plt 

def shiftfunc(data, amt):
    return sciim.interpolation.shift(data, amt, mode='wrap', order = 3)

if __name__ == "__main__":
    xvals = np.arange(100)*1.0

    yvals = np.sin(xvals*0.1)

    rollshift   = np.roll(yvals, 2)

    interpshift = shiftfunc(yvals, 2)

    plt.plot(xvals, rollshift, label = 'np.roll', alpha = 0.5)
    plt.plot(xvals, interpshift, label = 'interpolation.shift', alpha = 0.5)
    plt.legend()
    plt.show()

可以看出,前几组数值相差很大,其余的都没有问题。我怀疑这是使用 wrap 选项时预过滤和插值操作的实现错误。解决此问题的方法是修改 shiftfunc 以在移位值为整数时恢复为 np.roll,但这并不令人满意。

我是不是漏掉了什么明显的东西?

有没有办法让ndimage.shiftnp.roll重合?

我觉得shift功能没有什么问题。当你使用 roll 时,你需要切掉一个额外的元素以进行公平比较。请看下面的代码。

import numpy as np
import scipy.ndimage as sciim
import matplotlib.pyplot as plt 


def shiftfunc(data, amt):
    return sciim.interpolation.shift(data, amt, mode='wrap', order = 3)

def rollfunc(data,amt):
    rollshift   = np.roll(yvals, amt)
    # Here I remove one element (first one before rollshift) from the array 
    return np.concatenate((rollshift[:amt], rollshift[amt+1:]))

if __name__ == "__main__":
    shift_by = 5
    xvals = np.linspace(0,2*np.pi,20)
    yvals = np.sin(xvals)
    rollshift   = rollfunc(yvals, shift_by)
    interpshift = shiftfunc(yvals,shift_by)
    plt.plot(xvals, yvals, label = 'original', alpha = 0.5)
    plt.plot(xvals[1:], rollshift, label = 'np.roll', alpha = 0.5,marker='s')
    plt.plot(xvals, interpshift, label = 'interpolation.shift', alpha = 0.5,marker='o') 
    plt.legend()
    plt.show()

结果