在Pandas组的第一行开始迭代

时间:2017-03-01 15:00:08

标签: python pandas

我有这样的数据集:

Policy | Customer | Employee | CoveragDate | LapseDate
123    | 1234     | 1234     | 2011-06-01  | 2015-12-31
124    | 1234     | 1234     | 2016-01-01  | ?
125    | 1234     | 1234     | 2011-06-01  | 2012-01-01
124    | 5678     | 5555     | 2014-01-01  | ?

我正在尝试为每个客户的每个员工迭代每个政策(客户可以拥有许多员工,员工可以拥有多个政策),并将涵盖日期与特定员工的失效日期进行比较。如果涵盖日期和失效日期在5天之内,我想将该政策添加到结果列表中。

因此,预期的输出将是:

Policy | Customer | Employee
123    | 1234     | 1234

因为保单123的失效日期是在保单124的保单日期之后的5天内。

我在尝试迭代每组客户/员工号码时遇到了问题。我能够识别每个EmployeeID /客户编号(下面的EBCN)组中有多少行数据,但是我需要引用这些行中的特定数据来分配变量以进行比较。

到目前为止,我已经能够编写这段代码了:

import pandas
import datetime

wd = pandas.read_csv(DATASOURCE)
l = 0
for row, i in wd.groupby(['EMPID', 'EBCN']).size().iteritems():
    Covdt = pandas.to_datetime(wd.loc[l, 'CoverageEffDate'])
    for each in range(i):
        LapseDt = wd.loc[l, 'LapseDate']
        if LapseDt != '?':
            LapseDt = pandas.to_datetime(LapseDt) + datetime.timedelta(days=5)
            if Covdt < LapseDt:
                print('got one!')
        l = l + 1

此代码无效,因为我试图使用loc函数引用特定行的覆盖日期/失效日期,我的行号存储在'l'变量中。我最初认为Pandas会按照它们出现在我的数据集中的顺序遍历组,因此我可以简单地从l = 0开始(即数据中的第一行),根据它分配覆盖日期和失效日期变量,然后继续前进,但看起来Pandas开始随机迭代群组。因此,我确实得到了失效/覆盖日期的比较,但它们与最终得到代码输出的组无关。

我能想到的最佳解决方案是确定每个组的第一行的行号是什么,然后按该组中的行数向前迭代。

我已经阅读了一个关于找到群组第一行的问题,并且能够通过

这样做
wd.groupby(['EMPID','EBCN']).first()

但是我无法用我可以用loc函数引用的方式找出结果存储的行号。有没有办法将一个组的第一行的行号存储在一个变量或其他东西中,以便我可以从那里迭代我的覆盖日期和失效日期比较?

关于我的一般方法,我在这里阅读了这个问题,这与我的需求非常接近:

pandas computation in each group

但是,我需要将组中的每个策略与组中的其他策略进行比较 - 上面的问题只是将每个组中的最后一行与其他组进行比较。

有没有办法做我在Pandas / Python中尝试的事情?

1 个答案:

答案 0 :(得分:0)

对于将来需要此信息的任何人 - 我能够实施Boud的建议,使用pandas.merge_asof()函数替换上面的代码。我不得不做一些数据操作来获得所需的结果:

  1. 将数据框拆分为两个独立的框架 - 一个使用CoverageDate,另一个使用LapseDate。
  2. 更换&#39;?&#39;我的数据中的(null值)使用numpy.nan数据类型
  3. 按日期列
  4. 对左右数据框进行排序

    一旦数据格式正确,我就实现了合并:

    pandas.merge_asof(cov, term,
        on='Date',
        by='EMP|EBCN',
        tolerance=pandas.Timedelta('5 days'))
    

    注意&#39; cov&#39;是我的数据框包含覆盖日期,术语是带有失误的数据框。 &#39; EMP | EBCN&#39; column是员工ID和Customer#字段的连接列,以便于使用&#39; by&#39;字段。

    非常感谢Boud让我沿着正确的道路走下去!