麻烦与熊猫iterrows和循环计数器

时间:2016-05-07 17:54:25

标签: python python-2.7 pandas

我有一个数据集,其中包含几年内每天的美国财政部曲线。行=日期,列=特定国债的期限(3个月,1年,10年等)

我有每天循环的python代码并校准利率模型的参数。我无法通过iterrows和我的循环计数器循环遍历每一行。目标是逐行进行并将模型校准到每日曲线,将校准参数存储在数据框中,然后移动到下一行并重复。

def do_calibration_model1():
    global i
    for index, row in curves.iterrows():      
        day = np.array(row) #the subsequent error_fxn uses this daily curve
        calibration()
    i += 1

def calibration():
    i = 0
    param = scipy.brute(error_fxn, bounds...., etc.)
    opt = scipy.fmin(error_fxn, param, xtol..., ftol...)
    calibration.loc[i] = np.array(opt) # store result of minimization (parameters for that day)

代码在第一次迭代时正常工作,但随后不断重复数据帧中第一行的校准(曲线)。此外,它不将参数存储在校准数据帧的下一行中。我认为第一个问题与iterrows有关,而第二个问题是循环计数器的问题。

关于出了什么问题的任何想法?我有一个Matlab背景,发现熊猫设置非常令人沮丧。

作为参考,我已经查阅了下面的链接,但没有用。

https://www.python.org/dev/peps/pep-0212/

http://nipunbatra.github.io/2015/06/pandas-iteration/

根据Jason的评论,我已将代码更新为:

def do_calibration_model1():
    global i
    for index, row in curves.iterrows():
        for i in range(0,len(curves)):      
            day = np.array(row) #the subsequent error_fxn uses this daily curve
            param = scipy.brute(error_fxn, bounds...., etc.)
            opt = scipy.fmin(error_fxn, param, xtol..., ftol...)
            calibration.loc[i] = np.array(opt) # store result of minimization  (parameters for that day)
            i += 1

修改后的代码现在根据循环计数器将适当的参数放在校准数据帧的每一行中。

*但是,它仍然没有移动到pandas iterrows函数的曲线数据帧的第二行(或后续行)。

1 个答案:

答案 0 :(得分:2)

每次调用calibration时,都会设置i = 0。因此,当您致电calibration.loc[i] = np.array(opt)时,正在编写的内容是校准的第0项。变量i实际上从不在此函数中除0之外的其他任何东西。

在函数do_calibration_model1()中,您声明global i,然后在函数调用结束时将i加1。我不确定这个i计数器应该完成什么。也许您认为i中的do_calibration_model1()正在更新i函数中calibration()变量的值,但事实并非如此。鉴于global i中没有calibration()语句,此函数中的i是局部变量。

关于iterrows,我认为你不需要循环遍历曲线长度的嵌入式for循环。这是一个快速示例,向您展示iterrows的工作原理:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])

new = pd.DataFrame({'sum': [],
                    'mean': []})
for index, row in df.iterrows():
    temp = {'sum': sum(row), 'mean': np.mean(row)}
    new = new.append(temp, ignore_index=True)

在上文中,df看起来像这样:

          A         B         C         D
0 -2.197018  1.905543  0.773851 -0.006683
1  0.675442  0.818040 -0.561957  0.002737
2 -0.833482  0.248135 -1.159698 -0.302912
3  0.784216 -0.156225 -0.043505 -2.539486
4 -0.637248  0.034303 -1.405159 -1.590045
5  0.289257 -0.085030 -0.619899 -0.211158
6  0.804702 -0.838365  0.199911  0.210378
7 -0.031306  0.166793 -0.200867  1.343865

通过new循环填充的iterrows数据框如下所示:

       mean       sum
0  0.118923  0.475693
1  0.233566  0.934262
2 -0.511989 -2.047958
3 -0.488750 -1.954999
4 -0.899537 -3.598148
5 -0.156707 -0.626830
6  0.094157  0.376626
7  0.319621  1.278485

请注意,在此使用append不需要使用i计数器并简化代码。

回到你的代码,我建议如下:

def do_calibration_model1():
    callibration = pd.DataFrame({'a': [],
                                 'b': []})
    for index, row in curves.iterrows():   
        day = np.array(row)
        param = scipy.brute(error_fxn, bounds...., etc.)
        opt = scipy.fmin(error_fxn, param, xtol..., ftol...)
        temp = {'a': ..., 'b': ...}   # put opt values into dict
        callibration = calibration.append(temp, ignore_index=True)
    return callibration

在此步骤callibration = pd.DataFrame({'a': [], 'b': []})中,您需要设置数据框以提取opt。以前,您已将opt转换为numpy数组,但您需要排列opt的值,以便它们适合您的callibration数据帧,就像我在此处对temp进行的那样:{{1} }。