处理 pandas 中值的换行
Handling wrapping of values in pandas
我正在处理来自以 angular 坐标(俯仰、滚动和偏航)报告的位置传感器的数据。传感器读数使得最大读数为 180 度。超过这一点,读数就会跳到负数。例如,一系列轻微振荡的读数可能如下所示:
178.8
178.9
-178.8
-178.0
-179.0
180.0
179.0
我目前正在通过循环检查所有值来处理这个问题。我得到两个连续读数之间的增量,并保持 运行 总数以获得我当前的 angular 位置。如果我从第三象限(90 <= 先前值 <= 180)进入第四象限(-180 <= 当前值 <= -90),我在获取增量之前将 360 添加到当前值。如果我要从第四象限进入第三象限,我会在计算增量之前减去 360。例如:
Yaw = inData['Yaw']
cum_sum = Yaw[0]
for i in range(1, Yaw)):
x_prev = Yaw[i-1]
x = Yaw[i]
if 90 <= x_prev and x_prev <= 180 and -180 <= x and x <= -90:
x = x + 360
elif -180 <= x_prev and x_prev <= -90 and 90 <= x and x <= 180:
x = x - 360
else:
pass
delta = x - x_prev
cum_sum += delta
这里,inData 是一个包含来自多个轴的 angular 个位置的数据框,'Yaw' 是该数据框中的一个系列。
如果我可以对角度值进行一致的校正,我可以生成一系列增量并进行累加求和以获得位置。但是,将 360 添加到所有读数或使用角度作为模 360 只会将翻转点从 +/-180 之间的交叉点移动到 0 和 360 之间的交叉点。
鉴于我已经在 DataFrame/Series 中阅读了这些资料,我想知道是否有更 Pythonic(和更快)的方法来做到这一点。
全部矢量化,所以应该很快。
s = pd.Series([-178.8, 178.9, -178., -179., 180., 179.])
delta = (s.diff() +
(((s.shift() >= 90) & (s <= -90)).astype(int) -
((s.shift() <= -90) & (s >= 90)).astype(int)) * 360)
>>> delta.cumsum()
0 NaN
1 -2.3
2 0.8
3 -0.2
4 -1.2
5 -2.2
dtype: float64
关于逻辑,如果测量值位于左上象限,((s.shift() >= 90) & (s <= -90)).astype(int)
将计算为 1,否则计算为零。如果测量值位于右下象限,-((s.shift() <= -90) & (s >= 90)).astype(int)
将计算为负一,否则计算为零。这是一种矢量化的方式,表示如果您在左上象限,则应将差值加上 360,如果您在右下象限,则应从差值中减去 360,否则只取差值。
如果我理解你的话,象限是这样的(顺时针方向):
- 第一:-90 到 0 度。
- 第 2:从 0 到 90 度
- 第三:从 90 度到 180 度。
- 第 4:从 -180 度到 90 度。
如果是这样的话,我建议您先将您的讲座转换为常规的 360 度测量:
def parseSensorReading(readingDegrees):
if readingDegrees < 0:
degrees360 = readingDegrees + 360
degrees360 = readingDegrees
return degrees360
然后检测您正在阅读的象限:
def getQuadrant(degrees360):
if degrees360 < 360:
quadrant = 1
if degrees360 < 270:
quadrant = 4
if degrees360 < 180:
quadrant = 3
if degrees360 < 90:
quadrant = 2
return quadrant
有了象限,现在你可以计算增量了:
def getDelta(x_old, x_new):
q_old = getQuadrant(x_old)
q_new = getQuadrant(x_new)
if q_old == 1 and q_new == 2:
delta = (x_new + 360) - x_old
else:
delta = x_new - x_old
最后,您的代码变为:
yaw = inData["Yaw"]
cumSum = yaw[0]
for i in range(1, len(yaw) + 1)):
x_old = parseSensorReading(yaw[i-1])
x_new = parseSensorReading(yaw[i])
delta = getDelta(x_old, x_new)
cumSum += delta
注意:我更改了 for 循环中的 "range" 表达式,因为它使用列表 "yaw" 作为它的第二个参数。我假设您想说 len(yaw) + 1,所以 "i" 获取从 1 到 len(yaw) 的值。
我认为 np.unwrap()
可以做您想做的事,而不必弄乱增量和累积总和。 Docs
In [120]: data = pd.Series([178.8, 178.9, -178.8, -178.0, -179.0, 180.0, 179.0])
In [121]: np.degrees(np.unwrap(np.radians(data)))
Out[121]: array([ 178.8, 178.9, 181.2, 182. , 181. , 180. , 179. ])
它处理多个环绕:
In [124]: np.degrees(np.unwrap(np.radians(data + 540)))
Out[124]: array([ 718.8, 718.9, 721.2, 722. , 721. , 720. , 719. ])
我正在处理来自以 angular 坐标(俯仰、滚动和偏航)报告的位置传感器的数据。传感器读数使得最大读数为 180 度。超过这一点,读数就会跳到负数。例如,一系列轻微振荡的读数可能如下所示:
178.8
178.9
-178.8
-178.0
-179.0
180.0
179.0
我目前正在通过循环检查所有值来处理这个问题。我得到两个连续读数之间的增量,并保持 运行 总数以获得我当前的 angular 位置。如果我从第三象限(90 <= 先前值 <= 180)进入第四象限(-180 <= 当前值 <= -90),我在获取增量之前将 360 添加到当前值。如果我要从第四象限进入第三象限,我会在计算增量之前减去 360。例如:
Yaw = inData['Yaw']
cum_sum = Yaw[0]
for i in range(1, Yaw)):
x_prev = Yaw[i-1]
x = Yaw[i]
if 90 <= x_prev and x_prev <= 180 and -180 <= x and x <= -90:
x = x + 360
elif -180 <= x_prev and x_prev <= -90 and 90 <= x and x <= 180:
x = x - 360
else:
pass
delta = x - x_prev
cum_sum += delta
这里,inData 是一个包含来自多个轴的 angular 个位置的数据框,'Yaw' 是该数据框中的一个系列。
如果我可以对角度值进行一致的校正,我可以生成一系列增量并进行累加求和以获得位置。但是,将 360 添加到所有读数或使用角度作为模 360 只会将翻转点从 +/-180 之间的交叉点移动到 0 和 360 之间的交叉点。
鉴于我已经在 DataFrame/Series 中阅读了这些资料,我想知道是否有更 Pythonic(和更快)的方法来做到这一点。
全部矢量化,所以应该很快。
s = pd.Series([-178.8, 178.9, -178., -179., 180., 179.])
delta = (s.diff() +
(((s.shift() >= 90) & (s <= -90)).astype(int) -
((s.shift() <= -90) & (s >= 90)).astype(int)) * 360)
>>> delta.cumsum()
0 NaN
1 -2.3
2 0.8
3 -0.2
4 -1.2
5 -2.2
dtype: float64
关于逻辑,如果测量值位于左上象限,((s.shift() >= 90) & (s <= -90)).astype(int)
将计算为 1,否则计算为零。如果测量值位于右下象限,-((s.shift() <= -90) & (s >= 90)).astype(int)
将计算为负一,否则计算为零。这是一种矢量化的方式,表示如果您在左上象限,则应将差值加上 360,如果您在右下象限,则应从差值中减去 360,否则只取差值。
如果我理解你的话,象限是这样的(顺时针方向):
- 第一:-90 到 0 度。
- 第 2:从 0 到 90 度
- 第三:从 90 度到 180 度。
- 第 4:从 -180 度到 90 度。
如果是这样的话,我建议您先将您的讲座转换为常规的 360 度测量:
def parseSensorReading(readingDegrees):
if readingDegrees < 0:
degrees360 = readingDegrees + 360
degrees360 = readingDegrees
return degrees360
然后检测您正在阅读的象限:
def getQuadrant(degrees360):
if degrees360 < 360:
quadrant = 1
if degrees360 < 270:
quadrant = 4
if degrees360 < 180:
quadrant = 3
if degrees360 < 90:
quadrant = 2
return quadrant
有了象限,现在你可以计算增量了:
def getDelta(x_old, x_new):
q_old = getQuadrant(x_old)
q_new = getQuadrant(x_new)
if q_old == 1 and q_new == 2:
delta = (x_new + 360) - x_old
else:
delta = x_new - x_old
最后,您的代码变为:
yaw = inData["Yaw"]
cumSum = yaw[0]
for i in range(1, len(yaw) + 1)):
x_old = parseSensorReading(yaw[i-1])
x_new = parseSensorReading(yaw[i])
delta = getDelta(x_old, x_new)
cumSum += delta
注意:我更改了 for 循环中的 "range" 表达式,因为它使用列表 "yaw" 作为它的第二个参数。我假设您想说 len(yaw) + 1,所以 "i" 获取从 1 到 len(yaw) 的值。
我认为 np.unwrap()
可以做您想做的事,而不必弄乱增量和累积总和。 Docs
In [120]: data = pd.Series([178.8, 178.9, -178.8, -178.0, -179.0, 180.0, 179.0])
In [121]: np.degrees(np.unwrap(np.radians(data)))
Out[121]: array([ 178.8, 178.9, 181.2, 182. , 181. , 180. , 179. ])
它处理多个环绕:
In [124]: np.degrees(np.unwrap(np.radians(data + 540)))
Out[124]: array([ 718.8, 718.9, 721.2, 722. , 721. , 720. , 719. ])