【问题标题】:Start an iteration on first row of a group Pandas在 Pandas 组的第一行开始迭代
【发布时间】:2018-03-21 20:11:56
【问题描述】:

我有一个这样的数据集:

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 中做我正在尝试的事情?

【问题讨论】:

  • 我会添加 5 天到 lapse day,然后通过将 5 天的 timedelta 传递给容差参数来玩 pd.merge_asof
  • 是的!我用时间增量尝试了merge_asof,它返回了我想要的!非常感谢!!!
  • 您可以提交自己的解决方案,请这样做,以便更大的社区可以从您的问题和经验中受益。

标签: python pandas


【解决方案1】:

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

  1. 将数据帧拆分为两个单独的帧 - 一个带有 CoverageDate,一个带有 LapseDate。
  2. 替换“?” (空值)在我的数据中使用 numpy.nan 数据类型
  3. 按日期列对左右数据帧进行排序

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

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

注意“cov”是我的包含覆盖日期的数据框,term 是有失效的数据框。 “EMP|EBCN”列是员工 ID 和客户编号字段的串联列,以便于使用“by”字段。

非常感谢 Boud 让我走上正确的道路!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-20
    • 2017-06-18
    • 2023-04-01
    • 2015-09-29
    • 1970-01-01
    相关资源
    最近更新 更多