pandas_datareader调用Yahoo Finance报错:string indices must be integers
解决
pandas_datareader读取Yahoo Finance数据时的TypeError: string indices must be integers错误 问题背景
运行蒙特卡洛模拟Python代码时,调用wb.DataReader读取Yahoo Finance的BHIL股票数据,持续触发TypeError: string indices must be integers错误。已确认股票代码、时间范围无误,尝试过Adj Close和Adj Close**两种列名,问题仍未解决。
报错分析
从报错堆栈可以看到,错误发生在pandas_datareader的yahoo/daily.py第153行:
data = j["context"]["dispatcher"]["stores"]["HistoricalPriceStore"]
TypeError: string indices must be integers
这说明pandas_datareader尝试解析返回的JSON数据,但实际获取到的是字符串(而非预期的字典结构),根源是Yahoo Finance的API结构已变更,而旧版本的pandas_datareader未适配该变化,导致解析失败。
解决方案
最可靠的解决方式是改用yfinance库替代pandas_datareader的Yahoo数据源,yfinance专门维护Yahoo Finance的数据接口,兼容性更好:
- 安装
yfinance库:
pip install yfinance
- 替换原代码中读取数据的逻辑,用
yfinance获取数据。
完整修正代码
import numpy as np import pandas as pd import yfinance as yf import matplotlib.pyplot as plt import seaborn as sns from scipy.stats import norm ticker = "BHIL" data = pd.DataFrame() # 用yfinance下载数据,指定获取Adj Close列 data[ticker] = yf.download(ticker, start='2021-2-17')['Adj Close'] # 绘制价格走势 data.plot(figsize=(15,6)) log_return = np.log(1 + data.pct_change()) # 绘制日收益率分布 sns.distplot(log_return.iloc[1:]) plt.xlabel("Daily Return") plt.ylabel("Frequency") u = log_return.mean() var = log_return.var() drift = u - (0.5*var) stdev = log_return.std() days = 50 trials = 10000 Z = norm.ppf(np.random.rand(days, trials)) # days, trials daily_returns = np.exp(drift.values + stdev.values * Z) price_paths = np.zeros_like(daily_returns) price_paths[0] = data.iloc[-1] for t in range(1, days): price_paths[t] = price_paths[t-1]*daily_returns[t]
内容的提问来源于stack exchange,提问作者Greg Knight
相关产品推荐
相关产品推荐

