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

如何将按mmsi分组计算的船速序列插入DataFrame新列?

解决按MMSI分组计算连续行船速并赋值到新列的问题

你当前的代码问题在于:groupby.apply返回的是每个分组对应的列表,但直接赋值给新列时,每个分组的所有行都会被填充整个列表,而非将列表元素逐一对应到每行。以下是修正方案:

关键修正点

  1. 确保分组内的行按时间戳排序(否则连续行的时间逻辑错误)
  2. 修改速度计算函数,返回与分组行索引匹配的Series(而非列表),让Pandas能自动对齐行
  3. 处理分组后的索引,保证结果能正确映射到原DataFrame的每一行

完整代码示例

1. 先实现速度计算函数(以Haversine公式为例,你可替换为自己的计算逻辑)

import pandas as pd
import numpy as np

def calculate_speed(lons, lats, timestamps):
    # Haversine公式计算两点间海里距离
    def haversine(lon1, lat1, lon2, lat2):
        lon1, lat1, lon2, lat2 = map(np.radians, [lon1, lat1, lon2, lat2])
        dlon = lon2 - lon1
        dlat = lat2 - lat1
        a = np.sin(dlat/2)**2 + np.cos(lat1) * np.cos(lat2) * np.sin(dlon/2)**2
        c = 2 * np.arcsin(np.sqrt(a))
        return c * 3440.065  # 地球半径(海里)
    
    # 计算时间差(小时)
    time_diff = timestamps.diff().dt.total_seconds() / 3600
    
    # 计算连续点的距离
    dist = [np.nan]
    for i in range(1, len(lons)):
        dist.append(haversine(lons.iloc[i-1], lats.iloc[i-1], lons.iloc[i], lats.iloc[i]))
    
    # 计算速度(节,海里/小时)
    speed_knots = np.array(dist) / time_diff
    
    # 返回与分组行索引匹配的Series
    return pd.Series(speed_knots, index=lons.index)

2. 处理DataFrame并赋值新列

# 读取数据
df = pd.read_csv('filtered.csv')

# 保留存在重复MMSI的行
df = df[df.duplicated('mmsi', keep=False)]

# 转换时间戳为datetime格式
df['unix_datetime'] = pd.to_datetime(df['timestamp'], unit='s')

# 关键:按MMSI和时间戳排序,确保分组内的行是时间顺序
df = df.sort_values(['mmsi', 'timestamp'])

# 按MMSI分组计算速度,重置索引后赋值到新列
df['speed_knots'] = df.groupby('mmsi').apply(
    lambda x: calculate_speed(x.lon, x.lat, x.unix_datetime)
).reset_index(level=0, drop=True)

针对你原有函数的适配

如果你不想替换速度计算逻辑,只需修改原有speed函数的返回值,将列表转为对应索引的Series即可:

def speed(lons, lats, timestamps):
    # 你的原有计算逻辑
    ...
    speed_knots = speed_knots.tolist()
    # 返回与输入行索引匹配的Series
    return pd.Series(speed_knots, index=lons.index)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 18:15:30