我有这样的数据集:
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中尝试的事情?
答案 0 :(得分:0)
对于将来需要此信息的任何人 - 我能够实施Boud的建议,使用pandas.merge_asof()函数替换上面的代码。我不得不做一些数据操作来获得所需的结果:
一旦数据格式正确,我就实现了合并:
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让我沿着正确的道路走下去!