2014-07-15 50 views
1

我试图使用scipy.newton法在大熊猫数据帧进行优化。牛顿法在大熊猫

首先,我的数据帧创建如下。 二,创建函数Px。 第三,创建另一个函数YieldCalc,其中我使用scipy.newton来优化以找到Rate的值,使得Px = 0。然后我试图将该值添加到新列'Yield',但得到以下错误。任何帮助将非常感激。提前致谢。

from pandas import * 
import pandas as pd 
from scipy import * 
import scipy 
import timeit 
#In: 
#Creating Dataframe 
df = DataFrame(list([100,2,34.1556,9,100])) 
df = DataFrame.transpose(df) 
df = df.rename(columns={0:'Face',1:'Freq',2:'N',3:'C',4:'Mkt_Price'}) 
df2= df 
df = concat([df, df2]) 
df 

#Out: 
Face Freq N   C Mkt_Price 
100 2  34.1556  9 100 
100 2  34.1556  9 100 


#In: 
Face = df['Face'] 
Freq = df['Freq'] 
N = df['N'] 
C = df['C'] 
Mkt_Price = df['Mkt_Price'] 


def Px(Rate): 
    return Mkt_Price - (Face * (1 + Rate/Freq) ** (- N) + (C/Rate) * (1 - (1 + (Rate/Freq)) ** -N)) 

def YieldCalc(): 
    return scipy.optimize.newton(Px, .1, tol=.0001, maxiter=100) 
df['Yield'] = YieldCalc() 

错误/输出:

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-89-f4961d3f817b> in <module>() 
    12 def YieldCalc(Rate): 
    13  return scipy.optimize.newton(Px, .1, tol=.0001, maxiter=100) 
---> 14 df['Yield'] = YieldCalc(.05) 

<ipython-input-89-f4961d3f817b> in YieldCalc(Rate) 
    11 
    12 def YieldCalc(Rate): 
---> 13  return scipy.optimize.newton(Px, .1, tol=.0001, maxiter=100) 
    14 df['Yield'] = YieldCalc(.05) 

C:\Users\rebortz\Anaconda\lib\site-packages\scipy\optimize\zeros.pyc in newton(func, x0, fprime, args, tol, maxiter, fprime2) 
    145   q1 = func(*((p1,) + args)) 
    146   for iter in range(maxiter): 
--> 147    if q1 == q0: 
    148     if p1 != p0: 
    149      msg = "Tolerance of %s reached" % (p1 - p0) 

C:\Users\rebortz\Anaconda\lib\site-packages\pandas\core\generic.pyc in __nonzero__(self) 
    674   raise ValueError("The truth value of a {0} is ambiguous. " 
    675       "Use a.empty, a.bool(), a.item(), a.any() or a.all()." 
--> 676       .format(self.__class__.__name__)) 
    677 
    678  __bool__ = __nonzero__ 

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

是否加入'.values'到您的列(如'Mkt_price.values')修复错误? Iirc,熊猫数据框的标准布尔操作与numpy矩阵不同。 – FooBar

+0

刚刚尝试过。不工作。 –

+0

此外,如果您插入'df ['Yield'] = Px(.05)',它会为该Rate创建具有Px()的新列。所以我认为这与YieldCalc公式有关。 –

回答

1

这里的窍门的部分就是你从df['Face']后面是不是一个单一的值甚至数组。他们仍然与熊猫绑在一起。

您可以按照建议,开始由.values方式获得访问原始数据,并且把这个变成一个功能。

另外,熊猫的数据帧有.apply方法,让您拍摄功能,并运行它在每行或山坳。

我把在你发布的代码的末尾以下(注释掉的那一行第一)

def Foo(thing, Rate): 
    return thing[0]*Rate 

df['Yield'] = df.apply(Foo,axis=1,args=(0.1,)) 
df.head() 

在这里的.apply方法将通过功能Foo所有条目在给定行作为一系列的df,以及参数0.1。轴的规格是按行设置的(axis=0将执行此操作)。

只需重新组织Px即可接受'Rate'和从df(按该顺序)的一系列值。然后有YieldCalc也接受这个系列。此外,您需要在调用newton时使用args=条目,以在寻找零时将该系列值传递给Px

流程应该是:

.apply提出了一系列thing出一排从df并将它传递给YieldCalcYieldCalc运行newton on Px(Rate,thing)' to find费率返回0.然后,所有这些结果将被放入您的新收益列。