如何将NumPy权重数组与DataFrame中的股票代码正确映射?
权重与股票代码映射不匹配问题解决
我尝试将权重数组映射到股票代码列表,但权重和股票代码无法正确对应,且无报错。相关代码如下:
tickers_list=['GOOG','TSLA','AMZN','CP'] shares_owned=[100,700,200,50] total_shares =sum(shares_owned) ##-- TIME PERIOD --## from datetime import datetime from datetime import date start="2000-01-01" end="2023-01-01" #convert date to string import datetime format_str = '%Y-%m-%d' datetime_start = datetime.datetime.strptime(start, format_str) datetime_end = datetime.datetime.strptime(end, format_str) #DIFFERNCE BETWEEN START AND END DATES IN DAYS--- date_diff=(datetime_end-datetime_start) date_diff_days=date_diff.days data = yf.download(tickers_list, start, end)['Adj Close'] spy_ind=yf.download('^GSPC', start, end)['Adj Close'] # INDEX weights =np.random.random(len(tickers_list)) weights /=np.sum(weights) returns=(data/data.shift(1))-1 returns_index=(spy_ind/spy_ind.shift(1)) -1 weighted_returns=[] weighted_returns=shares_owned*returns weighted_returns['PORT_RETURN'] = weighted_returns.sum(axis=1)/total_shares Cumulative_ret = (returns+1).cumprod() Cumulative_index = (returns_index+1).cumprod() Cumulative_port_ret = (weighted_returns['PORT_RETURN']+1).cumprod() mean_daily_ret=returns.mean() mean_return_ann=(((returns.mean()*252)+1))-1 #annualize daily returns #mean_returns_dict = dict(zip(tickers_list, mean_return_ann)) std_dev=np.std(returns) import math #-----------MONTE CARLO SIMULATION--------------- for i in range (10): weights =np.random.random(len(tickers_list)) weights /=np.sum(weights) preturns.append(np.sum(mean_return_ann*weights)) print(mean_return_ann) print(weights) pvariances.append(np.sqrt(np.dot(weights.T,np.dot(returns.cov(),weights)))) pweights.append(weights) preturns =np.array(preturns) print("portfolio returns-------") print(preturns) max_ret = np.where(preturns == preturns.max()) #print(max_ret) maxReturn = np.amax(preturns) #print(maxReturn) #portfolio variance = w1²σ1² + w2²σ2² + 2w1w2Cov1,2 print("portfolio variances------") pvariances =np.array(pvariances) print(pvariances) pweights =np.array(pweights)
输出问题
输出中年化收益率与股票代码对应关系为:
AMZN 0.253906 CP 0.217467 GOOG 0.241529 TSLA 0.510510
生成的权重数组为[0.19824483 0.29516273 0.23614463 0.27044782],但DataFrame中对应关系错误:
RETURN OPT_WT STD DEV SHARPE RATIO SHARES_OWNED SHARES_OPT GOOG 0.241529 0.198245 30.750919 12.468428 100 20.0 TSLA 0.510510 0.295163 57.124065 14.186836 700 207.0 AMZN 0.253906 0.23614463 50.651217 7.957614 200 47.0 CP 0.217467 0.270448 30.531963 11.306763 50 14.0
已尝试join、concat等方法,仍无法解决,求解决方案。
解决方案
问题根源
核心问题是权重数组的顺序和DataFrame中股票代码的顺序不匹配:
- 自定义的
tickers_list顺序是['GOOG','TSLA','AMZN','CP'] - 但
yf.download返回的DataFrame列默认按字母排序(AMZN、CP、GOOG、TSLA),导致后续计算的mean_return_ann、权重数组的顺序和预期的股票代码顺序不一致。
具体修复步骤
强制DataFrame列顺序与tickers_list一致
在获取data后,手动指定列顺序,确保后续所有数据的列顺序和自定义列表一致:data = yf.download(tickers_list, start, end)['Adj Close'] # 强制列顺序与tickers_list完全匹配 data = data[tickers_list]将权重数组绑定股票代码索引
生成权重后,不要用纯数组存储,而是转换为带股票代码索引的Series,避免匹配时顺序错乱:# 以蒙特卡洛模拟中的权重存储为例,替换原pweights.append(weights) pweights.append(pd.Series(weights, index=tickers_list))合并数据时按索引匹配
后续构建结果DataFrame时,直接利用索引(股票代码)进行合并,而非依赖列顺序:# 示例:将收益率、权重等数据合并为结果表 result_df = pd.DataFrame({ 'RETURN': mean_return_ann, 'OPT_WT': weights_opt_series, # weights_opt_series是带索引的权重Series 'SHARES_OWNED': shares_owned }, index=tickers_list)
验证
调整后,检查mean_return_ann的输出顺序是否和tickers_list一致,再查看最终DataFrame中权重与股票代码的对应关系是否正确即可。
内容的提问来源于stack exchange,提问作者ivang
相关产品推荐
相关产品推荐

