python - 从函数+循环制作列表
问题描述
这是整个代码:我想创建一个循环,每次从输入文件中跳过一行。
导入 pandas 作为 pd
导入 numpy 作为 np 导入 matplotlib.pyplot 作为 plt 导入 seaborn 作为 sns 导入 quandl 导入 scipy.optimize 作为 sco from pandas.plotting 导入 register_matplotlib_converters register_matplotlib_converters()
mylist=[]
for i in range(0,4):
table = pd.read_excel(r"Priser.xlsx",skiprows=i,usecols="b,c,d,e,f,g,h,i,j,k,l,m,n,o,p")
table1 = np.array(table.values)
returns = np.log(table) - np.log(table.shift(1))
mean_returns = returns.mean()
cov_matrix = returns.cov()
num_portfolios = 1
risk_free_rate = 0.0178
def portfolio_annualised_performance(weights, mean_returns, cov_matrix):
returns = np.sum(mean_returns*weights ) *252
std = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights))) * np.sqrt(252)
return std, returns
def random_portfolios(num_portfolios, mean_returns, cov_matrix, risk_free_rate):
results = np.zeros((3,num_portfolios))
weights_record = []
for i in range(num_portfolios):
weights = np.random.random(15)
weights /= np.sum(weights)
weights_record.append(weights)
portfolio_std_dev, portfolio_return = portfolio_annualised_performance(weights, mean_returns, cov_matrix)
results[0,i] = portfolio_std_dev
results[1,i] = portfolio_return
results[2,i] = (portfolio_return - risk_free_rate) / portfolio_std_dev
return results, weights_record
def neg_sharpe_ratio(weights, mean_returns, cov_matrix, risk_free_rate):
p_var, p_ret = portfolio_annualised_performance(weights, mean_returns, cov_matrix)
return -(p_ret - risk_free_rate) / p_var
def max_sharpe_ratio(mean_returns, cov_matrix, risk_free_rate):
num_assets = len(mean_returns)
args = (mean_returns, cov_matrix, risk_free_rate)
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
bound = (0.0,1.0)
bounds = tuple(bound for asset in range(num_assets))
result = sco.minimize(neg_sharpe_ratio, num_assets*[1./num_assets,], args=args,
method='SLSQP', bounds=bounds, constraints=constraints)
return result
def portfolio_volatility(weights, mean_returns, cov_matrix):
return portfolio_annualised_performance(weights, mean_returns, cov_matrix)[0]
def min_variance(mean_returns, cov_matrix):
num_assets = len(mean_returns)
args = (mean_returns, cov_matrix)
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
bound = (0.0,0.15)
bounds = tuple(bound for asset in range(num_assets))
result = sco.minimize(portfolio_volatility, num_assets*[1./num_assets,], args=args,
method='SLSQP', bounds=bounds, constraints=constraints)
return result
def efficient_return(mean_returns, cov_matrix, target):
num_assets = len(mean_returns)
args = (mean_returns, cov_matrix)
def portfolio_return(weights):
return portfolio_annualised_performance(weights, mean_returns, cov_matrix)[1]
constraints = ({'type': 'eq', 'fun': lambda x: portfolio_return(x) - target},
{'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
bounds = tuple((0,1) for asset in range(num_assets))
result = sco.minimize(portfolio_volatility, num_assets*[1./num_assets,], args=args, method='SLSQP', bounds=bounds, constraints=constraints)
return result
def efficient_frontier(mean_returns, cov_matrix, returns_range):
efficients = []
for ret in returns_range:
efficients.append(efficient_return(mean_returns, cov_matrix, ret))
return efficients
def display_calculated_ef_with_random(mean_returns, cov_matrix, num_portfolios, risk_free_rate):
results, _ = random_portfolios(num_portfolios,mean_returns, cov_matrix, risk_free_rate)
max_sharpe = max_sharpe_ratio(mean_returns, cov_matrix, risk_free_rate)
sdp, rp = portfolio_annualised_performance(max_sharpe['x'], mean_returns, cov_matrix)
max_sharpe_allocation = pd.DataFrame(max_sharpe.x,index=table.columns,columns=['allocation'])
max_sharpe_allocation.allocation = [round(i*100,2)for i in max_sharpe_allocation.allocation]
max_sharpe_allocation = max_sharpe_allocation.T
min_vol = min_variance(mean_returns, cov_matrix)
sdp_min, rp_min = portfolio_annualised_performance(min_vol['x'], mean_returns, cov_matrix)
min_vol_allocation = pd.DataFrame(min_vol.x,columns=['allocation'])
min_vol_allocation.allocation = [round(i*100,2)for i in min_vol_allocation.allocation]
min_vol_allocation = min_vol_allocation.T
print (min_vol_allocation)
mylist.append(min_vol_allocation)
plt.figure(figsize=(10, 7))
plt.scatter(results[0,:],results[1,:],c=results[2,:],cmap='YlGnBu', marker='o', s=10, alpha=0.3)
plt.colorbar()
plt.scatter(sdp,rp,marker='*',color='r',s=500, label='Maximum Sharpe ratio')
plt.scatter(sdp_min,rp_min,marker='*',color='g',s=500, label='Minimum volatility')
target = np.linspace(rp_min, 0.32, 50)
efficient_portfolios = efficient_frontier(mean_returns, cov_matrix, target)
plt.plot([p['fun'] for p in efficient_portfolios], target, linestyle='-.', color='black', label='efficient frontier')
plt.title('Calculated Portfolio Optimization based on Efficient Frontier')
plt.xlabel('annualised volatility')
plt.ylabel('annualised returns')
plt.legend(labelspacing=0.8)
display_calculated_ef_with_random(mean_returns, cov_matrix, num_portfolios, risk_free_rate)
这给出了以下输出:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
allocation 0.0 3.51 0.15 2.4 0.59 12.58 6.04 15.0 8.55 3.63 2.55 15.0 15.0 15.0 0.0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
allocation 0.0 3.51 0.15 2.4 0.59 12.58 6.04 15.0 8.55 3.63 2.55 15.0 15.0 15.0 0.0
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
allocation 0.0 3.51 0.15 2.4 0.59 12.58 6.04 15.0 8.55 3.63 2.55 15.0 15.0 15.0 0.0
当代码在循环中运行时,我想将分配中的所有值保存到列表中。我无法弄清楚如何使用附加功能来做到这一点。
解决方案
我认为您的问题归结为在错误的时间做事。您当前的代码结构非常奇怪,您的函数定义在一个循环中(因此它们不断被重新定义),但仅在循环结束后调用:
my_list = []
for x in whatever():
def foo(arg):
my_list.append(arg)
foo(x)
这没有多大意义。该函数不依赖于x
,并且调用只发生在最后一个x
值(以及函数的最后一个定义,因为每个定义都是相同的,所以这部分并不重要)。
你应该重新安排事情。在循环外定义所有函数,并在其中调用它们:
my_list = []
def foo(arg):
mylist.append(arg)
for x in whatever():
foo(x)
此调用foo
(仅定义一次!)为每个值x
获取。该函数将每个附加到my_list
(这非常简化,您的真实代码将进行大量处理并附加结果)。请注意,让函数执行附加可能并不理想。函数对其结果可能更有意义return
,并让调用代码决定如何处理它。该设计可能允许您使用列表推导或map
函数。
推荐阅读
- angular - 使用对象数组和 *ngFor 动态添加 Angular 组件
- jquery - 如何使用 jquery table2Excel 或 tableHTMLExport.js 将 html 表的不同页面中的所有数据显示为 excel?
- outlook - 如何使用 OfficeJS 或 Graph API 在 Outlook 中获取分发列表(而不是组)及其成员?
- mysql - 在 mysql 中创建表和数据库时出现错误 1064 (42000)
- c# - 通过 C# 中的 Microsoft Graph API 更新用户的登录电子邮件地址
- jmeter - 多个随机值 Jmeter
- android - 我们如何打印 XML 布局
- php - 从控制器重定向在 CodeIgniter 3 (PHP) 中不起作用
- dpdk - 在使用 DPDK 运行管道应用程序时无法将 IOVA 用作 PA
- mongodb - Mongoose 文档未使用 expireAfterSeconds 过期