You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配对船舶MMSI并生成含时间范围的新DataFrame

船舶配对组聚合解决方案

问题描述

我有一个包含两艘船舶MMSI、坐标及datetime字段的DataFrame,想要生成一个新DataFrame,首列为船舶配对组,同时包含starttime、endtime、own_coord、target_coord字段。试过groupby等多种逻辑都没成功,求实现配对及时间范围提取的方法。

已通过以下代码处理初始DataFrame:

df2 = result.groupby(['own_mmsi', 'target_mmsi', 'datetime']).apply(
    lambda x: pd.Series({
        'own_lat': x['own_geometry'].iloc[0].y,   # 从own_geometry提取纬度
        'own_lon': x['own_geometry'].iloc[0].x,   # 从own_geometry提取经度
        'target_lat': x['target_geometry'].iloc[0].y,  # 从target_geometry提取纬度
        'target_lon': x['target_geometry'].iloc[0].x  # 从target_geometry提取经度
    })).reset_index()

可通过以下示例代码复现当前DataFrame:

data = {
    'own_mmsi': [212979000, 212979000, 212979000, 219592000, 236385000, 236385000, 244013009, 244389000, 244870428],
    'target_mmsi': [219592000, 245451000, 245451000, 212979000, 244013009, 244013009, 236385000, 244870428, 249557000],
    'datetime': [
        '2019-01-01 19:07:00', '2019-01-01 22:40:00', '2019-01-01 22:41:00',
        '2019-01-01 19:07:00', '2019-01-01 08:03:00', '2019-01-01 08:04:00',
        '2019-01-01 08:04:00', '2019-01-01 20:51:00', '2019-01-01 21:17:00',
    ],
    'own_lat': [59.148778, 59.704833, 59.707727, 59.150080, 59.330711, 59.330400, 59.327970, 59.111900, 59.106500],
    'own_lon': [10.665456, 10.595289, 10.593991, 10.645380, 10.515833, 10.514336, 10.515833, 9.606330, 9.623235],
    'target_lat': [59.150080, 59.706086, 59.702300, 59.148778, 59.327478, 59.327970, 59.330400, 59.105400, 59.098800],
    'target_lon': [10.645380, 10.579714, 10.582900, 10.665456, 10.515475, 10.515833, 10.514336, 9.627594, 9.599260],
}

df = pd.DataFrame(data)

解决方案

1. 统一船舶配对组标识

首先解决双向配对去重问题(如MMSI A→B和B→A视为同一组),通过排序MMSI生成固定格式的配对组ID:

import pandas as pd

# 转换datetime为时间类型
df['datetime'] = pd.to_datetime(df['datetime'])

# 生成配对组:将两个MMSI排序后拼接
df['pair_group'] = df.apply(
    lambda row: f"{min(row['own_mmsi'], row['target_mmsi'])}_{max(row['own_mmsi'], row['target_mmsi'])}",
    axis=1
)

2. 按配对组聚合提取数据

按配对组分组,计算时间范围并整理坐标序列:

# 定义聚合逻辑
def aggregate_pair(group):
    # 按时间排序保证坐标时序正确
    group_sorted = group.sort_values('datetime')
    return pd.Series({
        'starttime': group_sorted['datetime'].min(),
        'endtime': group_sorted['datetime'].max(),
        'own_coord': list(zip(group_sorted['own_lat'], group_sorted['own_lon'])),
        'target_coord': list(zip(group_sorted['target_lat'], group_sorted['target_lon']))
    })

# 分组聚合并重置索引
result_df = df.groupby('pair_group').apply(aggregate_pair).reset_index()

# 调整列顺序,将配对组放在首列
result_df = result_df[['pair_group', 'starttime', 'endtime', 'own_coord', 'target_coord']]

3. 最终结果示例

运行后result_df的输出结构如下:

pair_groupstarttimeendtimeown_coordtarget_coord
212979000_2195920002019-01-01 19:07:002019-01-01 19:07:00[(59.148778, 10.665456), (59.15008, 10.64538)][(59.15008, 10.64538), (59.148778, 10.665456)]
212979000_2454510002019-01-01 22:40:002019-01-01 22:41:00[(59.704833, 10.595289), (59.707727, 10.593991)][(59.706086, 10.579714), (59.7023, 10.5829)]
236385000_2440130092019-01-01 08:03:002019-01-01 08:04:00[(59.330711, 10.515833), (59.3304, 10.514336), (59.32797, 10.515833)][(59.327478, 10.515475), (59.32797, 10.515833), (59.3304, 10.514336)]
244389000_2448704282019-01-01 20:51:002019-01-01 20:51:00[(59.1119, 9.60633)][(59.1054, 9.627594)]
244870428_2495570002019-01-01 21:17:002019-01-01 21:17:00[(59.1065, 9.623235)][(59.0988, 9.59926)]

关键说明

  • 配对组生成逻辑确保双向配对被归为同一组,避免重复统计。
  • 聚合前按时间排序,保证坐标序列的时间顺序正确。
  • 若需将坐标序列展开为每行一个时间点的格式,可去掉聚合中的list(zip(...)),保留时间维度进行分组。

内容的提问来源于stack exchange,提问作者sneha_jerin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 12:24:54