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

按日期拆分CSV数据:优化List of list of dictionaries方案及谷歌距离API应用

更优的行程拆分与距离汇总实现方案

嘿,针对你按日期拆分CSV行程数据并汇总当日距离的需求,我整理了几个比嵌套列表字典更高效的实现思路,结合Python工具链来做会更顺畅:

一、更高效的行程数据分组方案

你之前用的List[List[Dict]]结构虽然可行,但用按日期键分组的字典(Dict[date, List[Dict]])会更直观,查找和后续处理也更方便。这里推荐两种实现方式:

1. 用Pandas快速分组(适合大数据量)

Pandas的分组功能能帮你一行搞定日期分组,代码简洁且性能出色:

import pandas as pd

# 读取CSV并解析日期
df = pd.read_csv("your_trips.csv")
df["ShowingDateTime"] = pd.to_datetime(df["ShowingDateTime"])
# 提取日期作为分组键
df["trip_date"] = df["ShowingDateTime"].dt.date

# 按日期分组,转成你需要的字典结构
grouped_trips = df.groupby("trip_date").apply(lambda x: x[["Address", "City", "State"]].to_dict("records")).to_dict()

# 输出示例:键是日期对象,值是当日的地址列表
# {datetime.date(2017, 1, 4): [{'Address': '1234 Hodge Street', ...}], ...}

2. 用标准库轻量实现(无需额外依赖)

如果不想引入Pandas,用csv模块+collections.defaultdict也能轻松实现:

import csv
from collections import defaultdict
from datetime import datetime

grouped_trips = defaultdict(list)

with open("your_trips.csv", "r") as f:
    reader = csv.DictReader(f)
    for row in reader:
        # 解析日期(注意匹配CSV里的日期格式)
        trip_datetime = datetime.strptime(row["ShowingDateTime"], "%m/%d/%y %H:%M")
        trip_date = trip_datetime.date()
        # 提取地址信息加入对应日期的列表
        trip_info = {
            "Address": row["Address"],
            "City": row["City"],
            "State": row["State"]
        }
        grouped_trips[trip_date].append(trip_info)

# 转成普通字典(可选)
grouped_trips = dict(grouped_trips)

二、对接谷歌Distance API计算当日总距离

拿到按日期分组的行程后,接下来需要计算当日行程的连续距离总和(比如A→B→C的总距离是A到B + B到C)。这里用谷歌Distance Matrix API来实现:

核心思路

  1. 把当日的每个地址拼接成完整的地址字符串(比如"1234 Hodge Street, Brown, CA")
  2. 按顺序生成路线的起点-终点对(比如第1个地址→第2个,第2个→第3个...)
  3. 调用API获取路段距离(注意API的请求限制,避免频繁调用)
  4. 累加每个路段的距离,得到当日总距离

示例代码

import requests
import os

# 从环境变量读取API密钥(不要硬编码!)
GOOGLE_API_KEY = os.getenv("GOOGLE_DISTANCE_API_KEY")
API_URL = "https://maps.googleapis.com/maps/api/distancematrix/json"

def calculate_daily_total_distance(trip_addresses):
    if len(trip_addresses) < 2:
        return 0  # 只有一个地点没有行程距离
    
    total_distance = 0
    # 生成连续的地址对
    for i in range(len(trip_addresses)-1):
        origin = f"{trip_addresses[i]['Address']}, {trip_addresses[i]['City']}, {trip_addresses[i]['State']}"
        destination = f"{trip_addresses[i+1]['Address']}, {trip_addresses[i+1]['City']}, {trip_addresses[i+1]['State']}"
        
        params = {
            "origins": origin,
            "destinations": destination,
            "key": GOOGLE_API_KEY,
            "units": "imperial"  # 可选:metric用公里,imperial用英里
        }
        
        response = requests.get(API_URL, params=params)
        data = response.json()
        
        # 解析距离(注意处理API返回的错误情况)
        if data["status"] == "OK" and data["rows"][0]["elements"][0]["status"] == "OK":
            distance = data["rows"][0]["elements"][0]["distance"]["value"]
            total_distance += distance  # 单位是米,按需转换
        else:
            print(f"无法计算{origin}到{destination}的距离")
    
    return total_distance

# 遍历每个日期的行程,计算总距离
for trip_date, trips in grouped_trips.items():
    daily_distance = calculate_daily_total_distance(trips)
    print(f"{trip_date}的总行程距离:{daily_distance/1000:.2f}公里")

额外优化建议

  • 批量请求优化:谷歌API支持一次传递多个起点和终点,可以把当日的所有地址一次性传入,减少请求次数(比如origins=地址1|地址2,destinations=地址2|地址3),提升效率
  • 缓存机制:如果有重复的地址对,缓存已计算的距离,避免重复调用API
  • 错误处理:增加对API请求超时、配额耗尽等情况的处理,保证程序健壮性

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:23:59