我写了一些代码来移动一个数组,并试图将它概括为使用" shift"来处理非整数移位。 scipy.ndimage
中的函数。数据是循环的,因此结果应该环绕,就像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
重合?
答案 0 :(得分:1)
我认为班次功能没有任何问题。当你使用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()
结果