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

使用yfinance批量获取数据时首个标的S&P 500出现NaN值问题

问题:yfinance批量获取数据时首个标的早期数据全为NaN,单独获取却正常

我用yfinance下载历史金融数据,写了个函数批量获取多个标的的调整收盘价(Adj Close)。但列表里第一个标的“S&P 500”(代码^GSPC)在2000-01-03到2015-04-30左右的时间段返回全是NaN,单独拉取这个标的数据却完全正常。是不是我的代码操作有误?

相关代码:

import yfinance as yf
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import norm

# 1. 定义参数
tickers = {
    "S&P 500": "^GSPC",
    "Nasdaq": "^IXIC",
    "Financials": "XLF",
    "Technology": "XLK",
    "Healthcare": "XLV",
    "Energy": "XLE",
    "Airlines": "JETS"
}
start_date = "2000-01-01"
end_date = "2022-12-31"

# 2. 获取并整理数据
def fetch_data(tickers, start, end):
    data = yf.download(list(tickers.values()), start=start, end=end)["Adj Close"]
    data.columns = tickers.keys()
    return data

market_data = fetch_data(tickers, start_date, end_date)
print(market_data)
market_data.to_csv("market_data.csv")

输出示例:

S&P 500     Nasdaq  Financials  Technology  Healthcare  
Date                                                                   
2000-01-03        NaN  13.962523   11.351282   41.629448   20.980349   
2000-01-04        NaN  13.699696   10.855049   39.517487   20.504265   
2000-01-05        NaN  14.061081   10.769754   38.930832   20.320322   
2000-01-06        NaN  14.603155   11.242729   37.640156   20.385239   
2000-01-07        NaN  14.759212   11.428815   38.297241   20.634104  

原因与解决方法

核心原因

你在重命名列时犯了顺序匹配错误:

  • yfinance批量下载返回的列顺序和你传入的tickers.values()列表顺序一致,但直接用tickers.keys()重命名时,若Python版本低于3.7,字典keys()是无序的,会导致列名和实际数据错位;
  • 就算是Python 3.7+(字典有序),你也忽略了关键信息:JETS这个ETF是2015年5月才上市的,2015年之前它的数据全是NaN。之前的错误是把JETS的NaN数据错标给了S&P 500,而S&P 500的真实数据被分到了其他列。

解决方法

不要直接用tickers.keys()赋值列名,而是通过代码-名称的映射字典来精准重命名,确保每个标的代码对应正确的名称:

修改后的fetch_data函数:

def fetch_data(tickers, start, end):
    data = yf.download(list(tickers.values()), start=start, end=end)["Adj Close"]
    # 创建代码到名称的映射字典,批量替换列名
    rename_map = {code: name for name, code in tickers.items()}
    data = data.rename(columns=rename_map)
    return data

验证逻辑

运行修改后的代码后,你会发现S&P 500的早期数据正常显示,而JETS列在2015年之前的数值才是NaN,这符合实际上市时间逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 05:07:32