【问题标题】:Pandas- Comparing Rows inside a groupbyPandas-比较groupby中的行
【发布时间】:2021-09-08 20:57:13
【问题描述】:

我正在尝试比较 python groupby 中的行,并根据条件对这些行执行一些操作。

下面是我的数据集

ID SUBID billtype start_date end_Date used_bill_type
757911 40F8E Direct 7/1/2015 2/1/2021 []
757911 40F8E Modern 3/1/2021 8/1/2021 ["Direct"]
757911 D9F83 EA 7/1/2015 8/1/2021 []
757911 D9F83 Suites 4/1/2015 7/1/2021 ["EA"]
757911 D9F83 EA RI 10/1/2019 8/1/2021 ["EA","Suites"]
757911 6DFB5 EA 12/1/2017 4/1/2018 []
757911 6DFB5 Direct 8/1/2018 9/1/2020 ["EA"]
757911 6DFB5 Modern 9/1/2020 8/1/2021 ["EA","Direct"]

我想按 ID 和 SUBID 分组。 used_bill_type 列包含以前用于该 ID 和 SUBID 组合的帐单类型。因此,在第一行中,对于 ID -757911 和 SUBID -40F8E,第一次计费为 Direct,因此 used_bill_type 将为空,而在第二行对于相同的 ID -757911 和 SUBID -40F8E,第二个计费类型为 Modern,因此其之前的 used_bill_type 将是 Direct。

所以我想要一个输出,其中在 groupby 内比较行并在 used_bill_type

上执行删除操作

可以这么说,对于 ID -757911 和 SUBID -40F8EModern 于 2021 年 3 月 1 日添加,但之前添加了帐单类型 Direct 于 2/1/2021 结束,因此应该从该行的 used_bill_type 列表中弹出 Direct

因此,当添加一个计费类型时,如果其先前添加的计费类型在此新计费类型的 start_date 之前结束,则应从 used_bill_type 列表中删除该计费类型。

所以预期的输出应该是这样的:

ID SUBID billtype start_date end_Date used_bill_type
757911 40F8E Direct 7/1/2015 2/1/2021 []
757911 40F8E Modern 3/1/2021 8/1/2021 []
757911 D9F83 EA 7/1/2015 8/1/2021 []
757911 D9F83 Suites 4/1/2017 7/1/2021 ["EA"]
757911 D9F83 EA RI 10/1/2019 8/1/2021 ["EA","Suites"]
757911 6DFB5 EA 12/1/2017 4/1/2018 []
757911 6DFB5 Direct 8/1/2018 9/1/2020 []
757911 6DFB5 Modern 9/1/2020 8/1/2021 ["Direct"]

下面是创建Dataframe的代码

data = pd.DataFrame({'TPID' : [757911,757911,757911,757911,757911,77909646,77909646,77909646],
                    'SUBID': ['40F8E','40F8E','D9F83','D9F83','D9F83','6DFB5','6DFB5','6DFB5'],
                   'start_date': ['7/1/2015','3/1/2021','7/1/2015','4/1/2017','10/1/2019','12/1/2017','8/1/2018','9/1/2020'],
                    'end_Date': ['2/1/2021','8/1/2021','8/1/2021','7/1/2021','8/1/2021','4/1/2018','9/1/2020','8/1/2021'],
                    'used_bill_type': [[],["Direct"],[],["EA"],["EA","Suites"],[],["EA"],["EA","Direct"]]
                    })

【问题讨论】:

  • billtype 有具体的顺序吗?即:Direct<Modern<EA<Suites<EA RI 而且,相同的账单是否与您的示例具有相同的开始和结束日期?
  • 嘿 Babak,没有任何账单没有任何特定顺序,同样的账单也没有相同的开始或结束日期
  • 嘿巴巴克,我的错-我已经更新了表格中的日期。这个问题现在说得通了

标签: python pandas pandas-groupby


【解决方案1】:

这是一个尝试

def billing(sdf):
    btypes = tuple(zip(sdf.billtype, sdf.end_Date))
    sdf.used_bill_type = [
        [btype for btype, edate in btypes[:i] if edate >= sdate]
        for i, sdate in enumerate(sdf.start_date.values)
    ]
    return sdf

df = df.groupby(["TPID", "SUBID"]).apply(billing)

这似乎适用于以下数据框(我已将 'billtype' 列添加到您提供的示例中)

df = pd.DataFrame({
    'TPID' : [757911,757911,757911,757911,757911,77909646,77909646,77909646],
    'SUBID': ['40F8E','40F8E','D9F83','D9F83','D9F83','6DFB5','6DFB5','6DFB5'],
    'billtype': ['Direct', 'Modern', 'EA', 'Suites', 'EA RI', 'EA', 'Direct', 'Modern'],
    'start_date': ['7/1/2015','3/1/2021','7/1/2015','4/1/2017','10/1/2019','12/1/2017','8/1/2018','9/1/2020'],
    'end_Date': ['2/1/2021','8/1/2021','8/1/2021','7/1/2021','8/1/2021','4/1/2018','9/1/2020','8/1/2021'],
    'used_bill_type': [[],["Direct"],[],["EA"],["EA","Suites"],[],["EA"],["EA","Direct"]]
})
df.start_date = pd.to_datetime(df.start_date)
df.end_Date = pd.to_datetime(df.end_Date)

结果:

       TPID  SUBID billtype start_date   end_Date used_bill_type
0    757911  40F8E   Direct 2015-07-01 2021-02-01             []
1    757911  40F8E   Modern 2021-03-01 2021-08-01             []
2    757911  D9F83       EA 2015-07-01 2021-08-01             []
3    757911  D9F83   Suites 2017-04-01 2021-07-01           [EA]
4    757911  D9F83    EA RI 2019-10-01 2021-08-01   [EA, Suites]
5  77909646  6DFB5       EA 2017-12-01 2018-04-01             []
6  77909646  6DFB5   Direct 2018-08-01 2020-09-01             []
7  77909646  6DFB5   Modern 2020-09-01 2021-08-01       [Direct]

但感觉有点不稳定,因为输入的顺序必须完全正确(尤其是start_date-column)。

【讨论】:

  • 嘿蒂姆斯,非常感谢这个解决方案就像一个魅力。我还学到了一些关于列表理解的知识。再次感谢分享。
猜你喜欢
  • 2019-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多