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

如何将DataFrame的日期索引转换为字符串?及批量获取商品历史API数据的优化问询

解决API批量获取商品历史价格的两个核心问题

一、获取并转换DataFrame最后一行的索引日期

你之前用df.iloc[-1,0]拿到商品代码是因为iloc是按位置取行列值,而你要的是作为索引的日期,得换个方式操作:

正确步骤:

  1. 提取最后一行的索引:直接取索引的最后一个元素,这会返回对应的日期对象(如果你的索引是datetime类型):
    last_date_obj = df.index[-1]
    
  2. 转换为YYYY-MM-DD格式的字符串:
    • 如果索引是datetime64类型,用strftime方法格式化:
      last_date_str = last_date_obj.strftime('%Y-%m-%d')
      
    • 如果索引本身就是字符串类型,直接赋值即可:
      last_date_str = df.index[-1]
      
  3. 删除该日期的所有行:
    df = df.drop(last_date_str)
    

现在last_date_str就是你需要传入下一次API调用的endDate参数了。

二、更优的批量获取+去重方案

你当前删除不完整日期的思路是对的,这里给你优化流程,让批量获取更自动化且避免重复:

1. 先验证日期完整性(避免误删完整数据)

在删除最后一天前,先判断这一天的数据是否完整——比如假设每个完整日期应该包含所有商品(symbol)的数据,你可以统计每日商品数量对比基准值:

# 获取完整日期应有的商品数量(取第一个完整日期的数量作为基准)
full_symbol_count = df.groupby(level=0).count().iloc[0, 0]
# 统计最后一天的商品数量
last_day_count = df.groupby(level=0).count().iloc[-1, 0]

if last_day_count < full_symbol_count:
    # 最后一天数据不完整,删除并记录该日期为下一次的endDate
    last_date_str = df.index[-1].strftime('%Y-%m-%d')
    df = df.drop(last_date_str)
    next_end_date = last_date_str
else:
    # 最后一天数据完整,下一次取前一天作为endDate(避免重复获取)
    from datetime import timedelta
    next_end_date = (df.index[-1] - timedelta(days=1)).strftime('%Y-%m-%d')

2. 批量追加数据时的去重保障

每次获取新数据后,直接和总数据合并即可(因为是从新到旧获取,日期范围天然不重叠),但为了保险,可以基于「日期+商品代码」去重:

# 假设total_df是存储所有历史数据的总DataFrame
new_df = fetchData(initDate='1975-01-01', endDate=next_end_date, output_type='df')
# 先处理new_df的不完整日期(同上验证步骤)
# 合并数据
total_df = pd.concat([total_df, new_df])
# 去重:保留最新的重复记录(这里是较早的日期数据)
total_df = total_df.reset_index().drop_duplicates(subset=['index', 'symbol'], keep='last').set_index('index')

3. 完整自动循环获取示例

import pandas as pd
from datetime import timedelta

# 初始化总数据和起始参数
total_df = pd.DataFrame()
current_end_date = None  # 第一次调用无需传入endDate

while True:
    # 调用API获取数据
    if current_end_date:
        df = fetchData(initDate='1975-01-01', endDate=current_end_date, output_type='df')
    else:
        df = fetchData(initDate='1975-01-01', output_type='df')
    
    # 空DataFrame说明没有更多数据,退出循环
    if df.empty:
        break
    
    # 验证最后一天数据完整性
    full_symbol_count = df.groupby(level=0).count().iloc[0, 0]
    last_day_count = df.groupby(level=0).count().iloc[-1, 0]
    
    if last_day_count < full_symbol_count:
        current_end_date = df.index[-1].strftime('%Y-%m-%d')
        df = df.drop(current_end_date)
    else:
        current_end_date = (df.index[-1] - timedelta(days=1)).strftime('%Y-%m-%d')
    
    # 追加到总数据并去重
    total_df = pd.concat([total_df, df])
    total_df = total_df.reset_index().drop_duplicates(subset=['index', 'symbol'], keep='last').set_index('index')
    
    # 打印进度(可选)
    print(f"已获取至日期: {current_end_date}")

这个流程会自动循环获取所有完整的历史数据,无需手动干预,也不会产生重复记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 02:54:06