使用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
相关产品推荐
相关产品推荐

