蟒蛇| Pandas Dataframe:为 df A 中的每个条目找到 df B 中最接近的时间戳

西蒙

我是 python 熊猫的新手。我拥有的是 2 个熊猫数据框。在其他数据中,它们都包含一个时间戳列。

假设我们有 df A

x y z timestamp
1 2 3 1.4
4 5 6 1.73
7 8 9 4.1

和 df B 是:

x y z timestamp
7 4 1 1.7
8 5 2 1.73
9 6 3 3.5
4 5 6 4.8

我想为 A 中的每一行计算与 B 中最接近 A 中时间戳的位置的差异。我们可以假设 df 都按时间戳排序。然而,这些时间戳不共享相同的开始或结束时间,但肯定有一些重叠。

此外,两个数据帧的长度不一定相同。我有一个蛮力实现,它完全符合我的要求,而且我还可以轻松扩展以在时间戳之间进行潜在的插值——这是我想在改进版本中实现的。但是,我的实现速度非常慢。

我确信有一种更高效的方式来实现以下内容:

idxA = 0
idxB = 0
endA = len(A)
endB = len(B)

while idxA < endA and idxB < endB:
  currentA_ts = A['timestamp'][idxA]
  currentB_ts = B['timestamp'][idxB]
  if idxB < endB-1:
    nextB_ts = B['timestamp'][idxB+1]
    if abs(currentB_ts - currentA_ts) > abs(nextB_ts - currentA_ts):
      idxB += 1

  currentClosestB_row = B.iloc[idxB]
  currentA_row = A.iloc[idxA]

  B_location = currentClosestB_row[['x','y','z']]
  A_location = currentA_row[['x', 'y', 'z']]

  direction = get_direction_vector(B_location, A_location)

  currentA_row['dir_x'] = direction[0]
  currentA_row['dir_y'] = direction[1]
  currentA_row['dir_z'] = direction[2]

  out_df.append(currentA_row)

  idxA += 1

我希望代码片段阐明了我试图实现的目标。但是如上所述,这非常慢,因为 df A 和 B 都有几个 100k 条目。

我看到了两种改进上述代码的方法:

  1. 我如何尝试实现所描述的目标的一般结构。
  2. 我可以想象我如何使用 python 和 pandas 不是最佳的。我第一次使用熊猫,python 也不是我的主要编程语言 - 所以如果你看到可以改进的东西,请告诉我。

高度赞赏有关如何加速该代码的任何反馈。

提前谢谢了。

金巴利

将行匹配到最接近的值称为 an asof merge,即“左连接,除了我们匹配最近的键而不是相等的键” - 两列都需要排序。

>>> pd.merge_asof(df1, df2, on='timestamp', suffixes=('_a', '_b'), direction='nearest')
   x_a  y_a  z_a  timestamp  x_b  y_b  z_b
0    1    2    3       1.40    7    4    1
1    4    5    6       1.73    8    5    2
2    7    8    9       4.10    9    6    3

如果您希望能够减去 2 个时间戳列,则需要以不同的方式命名。您可以在合并前添加后缀:

>>> df = pd.merge_asof(df1.add_suffix('_a'), df2.add_suffix('_b'), direction='nearest',
...                    left_on='timestamp_a', right_on='timestamp_b')
>>> df['delta'] = df['timestamp_a'] - df['timestamp_b']
>>> df
   x_a  y_a  z_a  timestamp_a  x_b  y_b  z_b  timestamp_b  delta
0    1    2    3         1.40    7    4    1         1.70   -0.3
1    4    5    6         1.73    8    5    2         1.73    0.0
2    7    8    9         4.10    9    6    3         3.50    0.6

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章