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

如何将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、权重数组的顺序和预期的股票代码顺序不一致。

具体修复步骤

  1. 强制DataFrame列顺序与tickers_list一致
    在获取data后,手动指定列顺序,确保后续所有数据的列顺序和自定义列表一致:

    data = yf.download(tickers_list, start, end)['Adj Close']
    # 强制列顺序与tickers_list完全匹配
    data = data[tickers_list]
    
  2. 将权重数组绑定股票代码索引
    生成权重后,不要用纯数组存储,而是转换为带股票代码索引的Series,避免匹配时顺序错乱:

    # 以蒙特卡洛模拟中的权重存储为例,替换原pweights.append(weights)
    pweights.append(pd.Series(weights, index=tickers_list))
    
  3. 合并数据时按索引匹配
    后续构建结果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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 09:06:39