
在天文学或任何涉及周期性、环绕性数据的领域中,我们经常需要识别数据趋势的“逆转”点,例如行星的逆行运动。这类数据的特点是其坐标值在一个固定范围内(如0到360度)循环。当行星的运动方向发生改变时,其坐标会达到一个局部最大值或最小值,这标志着逆行或顺行的开始。
然而,当数据点跨越360度(或0度)边界时,传统的局部极值检测方法(如基于导数或相邻点比较)会遇到困难。例如,从359度移动到1度,实际上是顺时针方向的微小步进,但数值上的巨大跳变(359 -> 1)可能被误判为极值点,从而导致错误的逆行检测。
考虑以下两种情况:
正常逆行示例:
20.08.2010 169.01682 21.08.2010 169.05885 <- 逆行开始点 (局部最大值) 22.08.2010 169.00792
在这种情况下,坐标先增大后减小,21日的169.05885是一个明显的局部最大值,容易被检测到。
跨越边界的误判示例:
17.03.2010 358.41273 <- 并非逆行开始点 18.03.2010 0.39843 19.03.2010 2.39354
这里,坐标从358.41273变为0.39843,然后继续增大。尽管数值上看起来像是一个从大到小的“跳变”,但实际上这只是跨越了360度边界的正常顺行。传统的极值检测方法可能会将17日的358.41273误判为局部最大值。
为了解决这一问题,我们需要一种能够区分真实方向逆转和坐标边界环绕的鲁棒方法。
Pandas库提供了强大的数据处理能力,我们可以利用其diff()和shift()方法,结合一个关键的阈值判断,来准确识别360度环绕坐标中的逆行点。
首先,我们需要将数据整理成Pandas DataFrame。假设我们有日期和对应的坐标数据。
import pandas as pd
import io
# 示例数据,包含正常逆行和跨越边界两种情况
data = """
Date,Coords
13.03.2010,350.60172
14.03.2010,352.53184
15.03.2010,354.47785
16.03.2010,356.43861
17.03.2010,358.41273
18.03.2010,0.39843
19.03.2010,2.39354
20.03.2010,4.39545
21.03.2010,6.40106
22.03.2010,8.40673
23.03.2010,10.40828
24.03.2010,12.40098
25.03.2010,14.37956
26.03.2010,16.33824
13.08.2010,166.41245
14.08.2010,167.00584
15.08.2010,167.53165
16.08.2010,167.98625
17.08.2010,168.36589
18.08.2010,168.66672
19.08.2010,168.88494
20.08.2010,169.01682
21.08.2010,169.05885
22.08.2010,169.00792
23.08.2010,168.86147
24.08.2010,168.61771
25.08.2010,168.27591
26.08.2010,167.83665
"""
df = pd.read_csv(io.StringIO(data))
df['Date'] = pd.to_datetime(df['Date'], format='%d.%m.%Y') # 将日期列转换为日期时间类型
print("原始数据:")
print(df)该方法的核心在于以下几个步骤:
识别非边界跳跃的有效数据点 (m0) 我们首先要区分真正的运动和因坐标环绕(如从359度到1度)引起的数值跳变。通过计算相邻坐标的绝对差值,并设定一个合理的阈值,我们可以过滤掉那些由于跨越0/360度边界而产生的巨大数值差异。 c.diff().abs().le(threshold):c.diff()计算当前值与前一个值的差。abs()取绝对值。.le(threshold)判断这个绝对差值是否小于等于我们设定的阈值。如果小于等于阈值,说明这不是一个跨越边界的大跳变,而是一个正常的、小范围的运动。
检测局部最大值 (m1) 局部最大值表示行星从顺行(坐标增大)转为逆行(坐标减小)的点。我们通过比较当前坐标与前后相邻坐标来判断: c.gt(c.shift(-1)) & c.gt(c.shift()):当前坐标c大于下一个坐标c.shift(-1),并且当前坐标c大于上一个坐标c.shift()。这两个条件同时满足,说明当前点是一个局部最大值。
检测局部最小值 (m2) 局部最小值表示行星从逆行(坐标减小)转为顺行(坐标增大)的点。 c.lt(c.shift(-1)) & c.lt(c.shift()):当前坐标c小于下一个坐标c.shift(-1),并且当前坐标c小于上一个坐标c.shift()。这两个条件同时满足,说明当前点是一个局部最小值。
结合条件 (m1 | m2) 最终,我们将局部最大值和局部最小值的检测结果合并,得到所有可能的逆行/顺行转折点。
应用边界过滤 (& m0) 最关键的一步是,只有当一个点同时满足是局部极值并且其前后运动不是由360度边界环绕引起时,才被认为是真正的逆行点。我们将m1和m2分别与m0进行逻辑与操作。
c = df['Coords']
# 1. 识别非边界跳跃的有效数据点
# 设定阈值为1。这意味着如果相邻两点间的绝对坐标差值超过1,则认为发生了360度边界的跳跃,而不是真实的微小运动。
# 这个阈值需要根据数据的实际变化范围进行调整。
threshold = 1
m0 = c.diff().abs().le(threshold)
# 2. 检测局部最大值 (上行转下行)
# 当前值大于前一个值 且 当前值大于下一个值
m1 = (c.gt(c.shift(-1)) & c.gt(c.shift())) & m0
# 3. 检测局部最小值 (下行转上行)
# 当前值小于前一个值 且 当前值小于下一个值
m2 = (c.lt(c.shift(-1)) & c.lt(c.shift())) & m0
# 4. 结合所有逆行/顺行转折点
df['Reversal'] = m1 | m2
print("\n检测结果:")
print(df)运行上述代码,我们将得到以下输出:
原始数据:
Date Coords
0 2010-03-13 350.60172
1 2010-03-14 352.53184
2 2010-03-15 354.47785
3 2010-03-16 356.43861
4 2010-03-17 358.41273
5 2010-03-18 0.39843
6 2010-03-19 2.39354
7 2010-03-20 4.39545
8 2010-03-21 6.40106
9 2010-03-22 8.40673
10 2010-03-23 10.40828
11 2010-03-24 12.40098
12 2010-03-25 14.37956
13 2010-03-26 16.33824
14 2010-08-13 166.41245
15 2010-08-14 167.00584
16 2010-08-15 167.53165
17 2010-08-16 167.98625
18 2010-08-17 168.36589
19 2010-08-18 168.66672
20 2010-08-19 168.88494
21 2010-08-20 169.01682
22 2010-08-21 169.05885
23 2010-08-22 169.00792
24 2010-08-23 168.86147
25 2010-08-24 168.61771
26 2010-08-25 168.27591
27 2010-08-26 167.83665
检测结果:
Date Coords Reversal
0 2010-03-13 350.60172 False
1 2010-03-14 352.53184 False
2 2010-03-15 354.47785 False
3 2010-03-16 356.43861 False
4 2010-03-17 358.41273 False
5 2010-03-18 0.39843 False
6 2010-03-19 2.39354 False
7 2010-03-20 4.39545 False
8 2010-03-21 6.40106 False
9 2010-03-22 8.40673 False
10 2010-03-23 10.40828 False
11 2010-03-24 12.40098 False
12 2010-03-25 14.37956 False
13 2010-03-26 16.33824 False
14 2010-08-13 166.41245 False
15 2010-08-14 167.00584 False
16 2010-08-15 167.53165 False
17 2010-08-16 167.98625 False
18 2010-08-17 168.36589 False
19 2010-08-18 168.66672 False
20 2010-08-19 168.88494 False
21 2010-08-20 169.01682 False
22 2010-08-21 169.05885 True <- 成功识别真实逆行点
23 2010-08-22 169.00792 False
24 2010-08-23 168.86147 False
25 2010-08-24 168.61771 False
26 2010-08-25 168.27591 False
27 2010-08-26 167.83665 False从输出结果可以看出:
阈值选择的重要性: m0 = c.diff().abs().le(threshold) 中的 threshold 参数至关重要。它定义了相邻数据点之间允许的最大“正常”变化量。
数据平滑: 如果你的坐标数据包含较
以上就是利用Pandas精确检测360度环绕坐标中的逆行运动的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号