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

使用Python的yfinance下载股票数据时出现'Adj Close' KeyError

问题

尝试用Python的yfinance库下载SPY、QQQ、GLD、VTI、BND五只标的的5年历史股票数据,提取Adj Close列时触发KeyError错误。

代码

import yfinance as yf
import pandas as pd
from pandas_datareader import data as pdt
import datetime as dt
import numpy as np
from scipy.optimize import minimize

end_date = dt.datetime.now()
start_date = end_date - dt.timedelta(days=365*5)

tickers = ['SPY', 'QQQ', 'GLD', 'VTI', 'BND']

adj_close_df = pd.DataFrame()
for ticker in tickers:
    data = yf.download(ticker, start = start_date, end = end_date)
    adj_close_df[ticker] = data['Adj Close']
    
    print(adj_close_df)

报错信息

%runcell -i 0 C:/Users/User/Downloads/untitled0.py
[*********************100%***********************]  1 of 1 completed
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File ~\AppData\Local\spyder-6\envs\spyder-runtime\Lib\site-packages\pandas\core\indexes\base.py:3805, in Index.get_loc(self, key)
   3804 try:
-> 3805     return self._engine.get_loc(casted_key)
   3806 except KeyError as err:

File index.pyx:167, in pandas._libs.index.IndexEngine.get_loc()

File index.pyx:196, in pandas._libs.index.IndexEngine.get_loc()

File pandas\_libs\hashtable_class_helper.pxi:7081, in pandas._libs.hashtable.PyObjectHashTable.get_item()

File pandas\_libs\hashtable_class_helper.pxi:7089, in pandas._libs.hashtable.PyObjectHashTable.get_item()

KeyError: 'Adj Close'

The above exception was the direct cause of the following exception:

KeyError                                  Traceback (most recent call last)
File c:\users\user\downloads\untitled0.py:16
     14 for ticker in tickers:
     15     data = yf.download(ticker, start = start_date, end = end_date)
---> 16     adj_close_df[ticker] = data['Adj Close']
     18     print(adj_close_df)

File ~\AppData\Local\spyder-6\envs\spyder-runtime\Lib\site-packages\pandas\core\frame.py:4101, in DataFrame.__getitem__(self, key)
   4099 if is_single_key:
   4100     if self.columns.nlevels > 1:
-> 4101         return self._getitem_multilevel(key)
   4102     indexer = self.columns.get_loc(key)
   4103     if is_integer(indexer):

File ~\AppData\Local\spyder-6\envs\spyder-runtime\Lib\site-packages\pandas\core\frame.py:4159, in DataFrame._getitem_multilevel(self, key)
   4157 def _getitem_multilevel(self, key):
   4158     # self.columns is a MultiIndex
-> 4159     loc = self.columns.get_loc(key)
   4160     if isinstance(loc, (slice, np.ndarray)):
   4161         new_columns = self.columns[loc]

File ~\AppData\Local\spyder-6\envs\spyder-runtime\Lib\site-packages\pandas\core\indexes\multi.py:3040, in MultiIndex.get_loc(self, key)
   3037     return mask
   3039 if not isinstance(key, tuple):
-> 3040     loc = self._get_level_indexer(key, level=0)
   3041     return _maybe_to_slice(loc)
   3043 keylen = len(key)

File ~\AppData\Local\spyder-6\envs\spyder-runtime\Lib\site-packages\pandas\core\indexes\multi.py:3391, in MultiIndex._get_level_indexer(self, key, level, indexer)
   3388         return slice(i, j, step)
   3390 else:
-> 3391     idx = self._get_loc_single_level_index(level_index, key)
   3393     if level > 0 or self._lexsort_depth == 0:
   3394         # Desired level is not sorted
   3395         if isinstance(idx, slice):
   3396             # test_get_loc_partial_timestamp_multiindex

File ~\AppData\Local\spyder-6\envs\spyder-runtime\Lib\site-packages\pandas\core\indexes\multi.py:2980, in MultiIndex._get_loc_single_level_index(self, level_index, key)
   2978     return -1
   2979 else:
-> 2980     return level_index.get_loc(key)

File ~\AppData\Local\spyder-6\envs\spyder-runtime\Lib\site-packages\pandas\core\indexes\base.py:3812, in Index.get_loc(self, key)
   3807     if isinstance(casted_key, slice) or (
   3808         isinstance(casted_key, abc.Iterable)
   3809         and any(isinstance(x, slice) for x in casted_key)
   3810     ):
   3811         raise InvalidIndexError(key)
-> 3812     raise KeyError(key) from err
   3813 except TypeError:
   3814     # If we have a listlike key, _check_indexing_error will raise
   3815     #  InvalidIndexError. Otherwise we fall through and re-raise
   3816     #  the TypeError.
   3817     self._check_indexing_error(key)

KeyError: 'Adj Close'

解决方案

1. 先确认数据的列结构

yfinance部分版本返回的数据可能存在多级列索引,先打印列名确认:

for ticker in tickers:
    data = yf.download(ticker, start=start_date, end=end_date)
    print(f"{ticker} 列名:", data.columns)

如果输出是多级索引(比如MultiIndex([('Adj Close',), ...],)),则需要用元组索引:data[('Adj Close',)],或者用data.xs('Adj Close', axis=1, level=0)提取对应列。

2. 直接指定下载目标列

避免列结构异常,下载时直接指定只获取调整后收盘价:

data = yf.download(ticker, start=start_date, end=end_date, progress=False)['Adj Close']

或者改用Ticker对象的history方法,新版yfinance中该方法返回的Close即为调整后收盘价:

data = yf.Ticker(ticker).history(start=start_date, end=end_date)['Close']

3. 批量下载优化代码

没必要循环单下载,直接批量获取所有标的数据,效率更高且避免单标的列结构问题:

adj_close_df = yf.download(tickers, start=start_date, end=end_date)['Adj Close']

如果返回多级列索引,用以下方式提取:

adj_close_df = yf.download(tickers, start=start_date, end=end_date).xs('Adj Close', axis=1)

4. 升级yfinance到最新版本

旧版本yfinance可能存在列名或返回格式bug,执行升级命令修复:

pip install --upgrade yfinance

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 02:39:52