我是 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 条目。
我看到了两种改进上述代码的方法:
高度赞赏有关如何加速该代码的任何反馈。
提前谢谢了。
将行匹配到最接近的值称为 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] 删除。
我来说两句