Python获取S&P100股票数据遇NaN错误:寻求解决方案
问题排查与修正方案
以下是导致所有结果返回NaN的核心问题及修复后的代码:
核心问题分析
- 维基百科表格索引错误:原代码中
sp100_data[2]指向了错误的表格,导致获取的股票代码列表无效或为空,后续价格数据全部缺失。 - 特殊股票代码未兼容:S&P100中的
BRK.B、BF.B等含点的代码,yfinance需要转换为BRK-B、BF-B才能正常获取数据。 - 未转换为月度数据:原代码直接使用日度数据计算收益率,未按需求聚合为月度价格,且大量缺失数据导致统计结果全NaN。
- FRED数据缺失值未处理:DGS1MO存在部分日期的缺失值,直接取均值会返回NaN。
修复后的完整代码
import pandas as pd import pandas_datareader.data as pdr import yfinance as yf yf.pdr_override() # 1. 获取S&P100成分股列表 url = "https://en.wikipedia.org/wiki/S%26P_100" sp100_data = pd.read_html(url) # 修正:当前维基百科中成分股表格为索引1的表格 sp100_table = sp100_data[1] sp100_tickers = sp100_table["Symbol"].tolist() # 处理含点的股票代码,转换为yfinance兼容格式 sp100_tickers = [ticker.replace('.', '-') for ticker in sp100_tickers] start_date = "2010-01-01" end_date = "2023-10-27" # 2. 获取日度价格数据并转换为月度数据(取每月最后一个交易日的调整收盘价) price_data = pdr.get_data_yahoo(sp100_tickers, start_date, end_date) monthly_prices = price_data["Adj Close"].resample('M').last() # 3. 计算月度收益率 monthly_returns = monthly_prices.pct_change().dropna() # 4. 计算均值收益与协方差矩阵 mean_returns = monthly_returns.mean() cov_matrix = monthly_returns.cov() # 5. 获取FRED的DGS1MO数据并处理缺失值,计算平均无风险利率 t_bill_rates = pdr.DataReader("DGS1MO", "fred", start_date, end_date) # 前向填充缺失值,再转换为月度数据(取每月均值) monthly_t_bills = t_bill_rates.ffill().resample('M').mean() average_rf_rate = monthly_t_bills.mean()[0] print("Mean Returns:") print(mean_returns) print("\nCovariance Matrix:") print(cov_matrix) print(f"\nAverage Risk-Free Rate: {average_rf_rate:.4f}%")
关键修正说明
- 表格索引修正:通过确认维基百科页面结构,将表格索引从
2改为1,确保获取正确的成分股列表。 - 股票代码转换:将含点的代码替换为横杠,兼容yfinance的API要求。
- 月度数据聚合:使用
resample('M').last()将日度收盘价转换为月度数据,再计算月度收益率,符合任务需求。 - 缺失值处理:对FRED的国债利率数据使用
ffill()填充缺失值,再取月度均值,避免因缺失值导致平均利率为NaN。
内容的提问来源于stack exchange,提问作者Kassidy KIrlin
相关产品推荐
相关产品推荐

