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.shift
和np.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()
结果
我写了一些代码来移动数组,并试图使用 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.shift
和np.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()
结果