bounded circular interpolation in python

别等时光非礼了梦想. 提交于 2020-01-21 04:37:04

问题


My question is something similar to the question here. In simple term I have a time series angle data which is bounded between [0, 360]. I need to compute an iterpolation between measurements. Currently, I am using scipy.interpolate.interp1d. To make my question clear here is an example,

import numpy as np
from scipy import interpolate
data = np.array([[0, 2, 4], [1, 359, 1]]) # first row time index, second row angle measurements
f = interpolate.interp1d(data[0, :], data[1, :], kind='linear', bounds_error=False, fill_value=None)
f([1, 3])

this will result in [ 180., 180.]. However between time 2 and time 4 the angle changed from 359 to 1, that is only a 2 degree change and the interpolated value at 3 should have been 0. The angles are changing in CCW direction through time.

Finally, my question is this,

Is there any standard module that I can use to achieve this?

Just because I want to avoid custom method as much as possible!


回答1:


Just add the 360° complement each time you detect there is a jump and revert back to the first 360 degrees by using the modulo operation. For example:

In [1]: import numpy as np

In [2]: from scipy import interpolate

In [3]: data = np.array([[0, 2, 4, 6, 8], [1, 179, 211, 359, 1]])

In [4]: complement360 = np.rad2deg(np.unwrap(np.deg2rad(data[1])))

In [5]: complement360
Out[5]: array([   1.,  179.,  211.,  359.,  361.])

In [6]: f = interpolate.interp1d(data[0], complement360, kind='linear', bounds_error=False, fill_value=None)

In [7]: f(np.arange(9))
Out[7]: array([   1.,   90.,  179.,  195.,  211.,  285.,  359.,  360.,  361.])

In [8]: f(np.arange(9))%360
Out[8]: array([   1.,   90.,  179.,  195.,  211.,  285.,  359.,    0.,    1.])

Remark, I did add a few extra values here, as otherwise there is no realistic way for np.unwrap to know in which direction the angle is increasing, and that is probably also how you know it is increasing in that way (the difference between consecutive values is less than 180° unless there's an actual discontinuity).

If however you really have data that makes angular jumps larger than 180° between 2 consecutive items, but you know the direction in which the angles are changing (e.g. CCW) and that it is changing monotonously, then you could detect it like so:

In [31]: data = np.array([1, 359, 1, 60, 359, 177, 2])  # mock-data

In [32]: jumps = np.diff(data)<0  # assumptions: angle increases stricly monotonously CCW

In [33]: np.hstack((data[0], data[1:] + np.cumsum(np.sign(d)<0)*360))
Out[33]: array([   1,  359,  361,  420,  719,  897, 1082])



回答2:


As of version 1.10.0, numpy.interp takes a period keyword: http://docs.scipy.org/doc/numpy/reference/generated/numpy.interp.html



来源:https://stackoverflow.com/questions/27295494/bounded-circular-interpolation-in-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!