我正在尝试使用scipy.newton方法在pandas数据帧中进行优化。
首先,我的数据框创建如下。 其次,创建函数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().
答案 0 :(得分:1)
这里的部分技巧是从df['Face']
返回的不是单个值甚至是数组。他们仍然与大熊猫有关。
您可以按照建议开始通过.values
访问原始数据并将其提供给函数。
或者,pandas数据框有一个.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
将执行col)。
只需重新组织Px
即可接受'费率'和来自df
的一系列值(按此顺序)。然后让YieldCalc
接受该系列。此外,您需要在args=
调用中使用newton
条目,以便在搜索零时将该系列值传递给Px
。
流程应该是:
.apply
在thing
的一行中生成一系列df
,并将其传递给YieldCalc
。 YieldCalc
在newton
Rate`上运行Px(Rate,thing)' to find
返回0.然后,所有这些结果都会被放入新的Yield列中。