系列的真实值是不明确的。对np.argmax使用a.empty,a.bool(),a.item(),a.any()或a.all()

时间:2019-04-16 20:56:09

标签: python python-3.x numpy

我遇到了错误:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

即使我没有评估任何陈述。当我尝试通过此错误时出现

max_sharpe_idx = np.argmax(results[2])

结果先前以

传递
results = np.zeros((3,num_portfolios), object)

,结果[2]是一个浮点数数组。

为什么会引发此错误,我无法理解,有什么想法吗? 如有需要,可以提供全部功能。

编辑:填充结果的函数:

def random_portfolios(num_portfolios, mean_returns, cov_matrix, risk_free_rate):
    results = np.zeros((3,num_portfolios), object)
    weights_record = []
    for i in range(num_portfolios):
        weights = np.random.random(12)
        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

更新:打印结果类型和结果[2,0]时,这是输出:

results: <class 'numpy.ndarray'>
results[2,0]: <class 'pandas.core.series.Series'>

可能引起问题的变量是:

portfolio_return <class 'pandas.core.series.Series'>

Portfolio_return的输出如下:

ABB.ST          0.043190
ALFA.ST         0.015955
AMD             0.031319
SAAB-B.ST       0.018625
ERIC-B.ST       0.080382
FORTUM.HE       0.013456
INVE-B.ST       0.044658
NDA-SE.ST       0.027568
NOKIA-SEK.ST    0.040725
SWED-A.ST       0.013694
TEL2-B.ST       0.038682
VOLV-B.ST       0.003941
dtype: float64

由于投资组合回报是以下来源的输出:

mean_returns = returns.mean()
pandas.core.series.Series

我该如何解决? 完整的代码(如果需要):https://github.com/timoudas/PortfolioOpt 但是结论是,存在一个我不知道如何解决的潜在数据结构问题

2 个答案:

答案 0 :(得分:0)

似乎results[2]不是浮点数数组,否则您提供的内容将起作用。如果可以转换,

np.argmax(results[2].astype(float)) 

应该这样做。如果产生

  

ValueError:设置具有序列的数组元素。

然后我认为原因是您的numpy数组不仅包含数字,而且还包含其他对象(例如字符串)。您的数组最初为object类型,这很有可能。我建议您看一下this帖子,并确保您的对象绝对不含浮点数/整数。

答案 1 :(得分:0)

Let's take seriously the error message:

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

The problem must be an array element that is a pandas Series!

In [145]: import pandas as pd                                                   
In [146]: S = pd.Series(np.arange(10))                                          

In [148]: x = np.empty(3,object)                                                
In [150]: x[:]=[S,S,S]                                                          
In [151]: x                                                                     
Out[151]: 
array([0    0
1    1
2    2
3    3
4    4
5    5
6    6
....
9    9
dtype: int64], dtype=object)

Now I can recreate your error message:

In [152]: np.argmax(x)                                                          
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-152-81bcc042be54> in <module>
----> 1 np.argmax(x)

/usr/local/lib/python3.6/dist-packages/numpy/core/fromnumeric.py in argmax(a, axis, out)
   1101 
   1102     """
-> 1103     return _wrapfunc(a, 'argmax', axis=axis, out=out)
   1104 
   1105 

/usr/local/lib/python3.6/dist-packages/numpy/core/fromnumeric.py in _wrapfunc(obj, method, *args, **kwds)
     54 def _wrapfunc(obj, method, *args, **kwds):
     55     try:
---> 56         return getattr(obj, method)(*args, **kwds)
     57 
     58     # An AttributeError occurs if the object does not have

/usr/local/lib/python3.6/dist-packages/pandas/core/generic.py in __nonzero__(self)
   1477         raise ValueError("The truth value of a {0} is ambiguous. "
   1478                          "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
-> 1479                          .format(self.__class__.__name__))
   1480 
   1481     __bool__ = __nonzero__

ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().

So you must have an object array that contains one or more Series

You give some code, but don't specify the nature (type) of the variables:

results[2,i] = (portfolio_return - risk_free_rate) / portfolio_std_dev