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

如何基于df_2线串替换df_1中缺失的经纬度NaN值?

问题描述

我有两个DataFrame:df_1和df_2。df_1中的经纬度代表一条线串,但存在缺失值(NaN);df_2包含人工绘制的线串经纬度对。我已经完成第一步:针对df_1中非NaN的经纬度值,找到df_2中距离最近的经纬度对,并添加到closest_latitude_in_df_2和closest_longitude_in_df_2列。

接下来需要把df_1中的NaN经纬度值替换为df_2中的对应值——利用df_1中非NaN行在df_2中对应点的后续点,填充中间的NaN值。


初始数据

df_1 数据:

import pandas as pd

data = {'ID': ['1', '1', '1', '1', '1', '3', '3', '3'],
        'time': ['2023-06-30 14:32:23','2023-06-30 14:33:23','2023-06-30 14:34:00','2023-06-30 14:34:15','2023-06-30 14:34:45','2023-06-30 14:35:00', '2023-06-30 14:35:10', '2023-06-30 14:35:20'],
        'latitude': [59.9139, "NaN", "NaN", 60.628330, 60.662330, 59.741371, 55.615864, 59.076984],
        'longitude': [10.7522, "NaN", "NaN", 6.401802, 6.892802, 10.176844, 13.040593, 9.864355],
        'closest_latitude_in_df_2': [59.9200, "NaN", "NaN", 60.63000, "NaN", "NaN", "NaN", "NaN"],
        'closest_longitude_in_df_2': [10.8000, "NaN", "NaN", 11.5000, "NaN", "NaN","NaN", "NaN"]
        }
df_1 = pd.DataFrame(data)
df_1['time'] = pd.to_datetime(df_1['time'])
# 预处理:将字符串"NaN"转为pandas可识别的NaN值
df_1[['latitude', 'longitude', 'closest_latitude_in_df_2', 'closest_longitude_in_df_2']] = df_1[['latitude', 'longitude', 'closest_latitude_in_df_2', 'closest_longitude_in_df_2']].apply(pd.to_numeric, errors='coerce')

df_2 数据:

data = {'latitude': [59.9000, 59.92000, 59.94000, 59.95000, 59.98000, 60.000000, 60.63000, 60.63500],
        'longitude': [10.2000, 10.8000, 10.8200, 10.8400, 10.8800, 10.9000, 11.5000, 11.5500]}
df_2 = pd.DataFrame(data)

期望结果

最终df_final中,df_1的NaN经纬度被df_2中对应后续点填充,示例如下:

data = {'ID': ['1', '1', '1', '1', '1', '3', '3', '3'],
        'time': ['2023-06-30 14:32:23','2023-06-30 14:33:23','2023-06-30 14:34:00','2023-06-30 14:34:15','2023-06-30 14:34:45','2023-06-30 14:35:00', '2023-06-30 14:35:10', '2023-06-30 14:35:20'],
        'latitude': [59.9139, 59.94000, 59.98000, 60.628330, 60.662330, 59.741371, 55.615864, 59.076984],
        'longitude': [10.7522, 10.8200, 10.8800, 6.401802, 6.892802, 10.176844, 13.040593, 9.864355],
        'closest_latitude_in_df_2': [59.9200, "NaN", "NaN", 60.63000, "NaN", "NaN", "NaN", "NaN"],
        'closest_longitude_in_df_2': [10.8000, "NaN", "NaN", 11.5000, "NaN", "NaN","NaN", "NaN"]
        }
df_final = pd.DataFrame(data)
df_final['time'] = pd.to_datetime(df_final['time'])
df_final[['latitude', 'longitude', 'closest_latitude_in_df_2', 'closest_longitude_in_df_2']] = df_final[['latitude', 'longitude', 'closest_latitude_in_df_2', 'closest_longitude_in_df_2']].apply(pd.to_numeric, errors='coerce')

解决方案

核心思路

  1. 为df_2的经纬度对建立索引映射,快速定位closest_latitude_in_df_2和closest_longitude_in_df_2在df_2中的位置。
  2. 按ID分组处理,因为不同ID对应独立线串,避免跨组干扰。
  3. 针对每组内的NaN区间,根据前后有效点在df_2中的索引,取对应数量的后续点填充缺失值。

代码实现

import pandas as pd

# 1. 为df_2创建坐标到索引的映射
df_2['coord_key'] = list(zip(df_2['latitude'], df_2['longitude']))
coord_to_idx = {coord: idx for idx, coord in enumerate(df_2['coord_key'])}

# 2. 定义分组填充函数
def fill_missing(group):
    # 筛选出有有效closest坐标的行
    valid_closest = group.dropna(subset=['closest_latitude_in_df_2', 'closest_longitude_in_df_2'])
    if len(valid_closest) < 2:
        # 若组内有效closest点不足2个,直接返回原组(比如ID=3的情况)
        return group
    
    # 获取起始和结束的closest坐标在df_2中的索引
    start_coord = (valid_closest.iloc[0]['closest_latitude_in_df_2'], valid_closest.iloc[0]['closest_longitude_in_df_2'])
    end_coord = (valid_closest.iloc[-1]['closest_latitude_in_df_2'], valid_closest.iloc[-1]['closest_longitude_in_df_2'])
    start_idx = coord_to_idx.get(start_coord)
    end_idx = coord_to_idx.get(end_coord)
    
    if start_idx is None or end_idx is None:
        return group
    
    # 计算需要填充的NaN数量,从df_2中取对应数量的后续点
    missing_count = group['latitude'].isna().sum()
    fill_coords = df_2.iloc[start_idx+1 : start_idx+1+missing_count][['latitude', 'longitude']].values
    
    # 填充到缺失位置
    group.loc[group['latitude'].isna(), ['latitude', 'longitude']] = fill_coords
    return group

# 3. 按ID分组执行填充
df_final = df_1.groupby('ID', group_keys=False).apply(fill_missing)

# 查看结果
print(df_final)

代码说明

  • 预处理:将原数据中的字符串"NaN"转为pandas可识别的NaN值,确保缺失值判断准确。
  • 坐标映射:通过元组键快速匹配closest坐标在df_2中的索引,提升查找效率。
  • 分组填充:针对每个ID的线串,仅当存在前后两个有效closest点时才填充,取df_2中起始点之后的连续点匹配缺失数量,和期望结果完全对齐。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 14:25:00