有效运行牛顿算法

时间:2014-07-18 22:02:39

标签: python numpy pandas scipy

这与我之前提到的另一个问题有关。我想在大型数据集上运行牛顿方法。下面是我使用循环创建的代码。我需要在大约5000万行上运行它并且循环非常笨重。有没有更有效的方法来使用Pandas / Numpy / ect运行它?提前致谢

In:
from pandas import *
from pylab import *
import pandas as pd
import pylab as plt
import numpy as np
from scipy import *
import scipy

df = DataFrame(list([100,2,34.1556,9,105,-100]))
df = DataFrame.transpose(df)
df = df.rename(columns={0:'Face',1:'Freq',2:'N',3:'C',4:'Mkt_Price',5:'Yield'})
df2= df
df = concat([df, df2])
df = df.reset_index(drop=True)
df

Out:
    Face    Freq    N        C Mkt_Price  Yield
0    100     2   34.1556     9   105    -100
1    100     2   34.1556     9   105    -100

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

for count, row in df.iterrows():
        Face = row['Face']
        Freq = row['Freq']
        N = row['N']
        C = row['C']
        Mkt_Price = row['Mkt_Price']
        row['Yield'] = scipy.optimize.newton(Px, .1, tol=.0001, maxiter=100)
df

Out:
    Face    Freq   N         C  Mkt_Price   Yield
0    100     2   34.1556     9   105       0.084419
1    100     2   34.1556     9   105       0.084419

1 个答案:

答案 0 :(得分:0)

我想到的一种可能性是你可能会进行矢量化。但是,您必须丢弃所有条件代码,然后运行所需的迭代次数。

Newton-Raphson的基本步骤始终相同,因此您不需要任何条件代码。您的函数Px看起来好像可以在没有任何额外工作的情况下进行矢量化。

步骤大致如下:

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

# initialize the iteration vector
y = 0.1 * np.zeros(num_rows)
# just a guess for the differentiation, might be smaller
h = 1e-6

# then iterate for a suitable number of iterations
for i in range(100):
    f = Px(y, Mkt_Price, Face, Freq, N, C)
    fp = Px(y+h, Mkt_Price, Face, Freq, N, C)
    y -= h * f / (fp - f)

在此之后,您将获得y的迭代结果。我假设Mkt_PriceFace等是5000万行向量。

将有数十亿的计算,所以这仍然需要十几秒钟。此外,没有错误检查,所以如果有什么东西疯狂地振荡,没有什么可以警告你。

使这更好的一种方法是分析计算第一个差异,就像它可以做到的那样。但是,实际的改进可能很小。您将不得不尝试找到最佳迭代次数。如果函数快速收敛(正如我想的那样),那么20次迭代就足够了。

代码完全未经测试,但它应该说明这个想法。