用另一列的值填充组中最后一项的一列

时间:2018-06-20 20:29:10

标签: python pandas pandas-groupby

我有每个案例分配的数据集。我正在尝试用unassigned日期填充每个案例的最后case_closed

case_nb   attorney      cas_closed_date assigned    last_event
1         A             2015-07-02      2015-07-02  2015-07-02
2         B             2015-09-10      2015-09-10  2015-09-10
3         C             2016-03-24      2016-03-24  2016-03-24
4         D             2018-06-07      2013-10-21  2014-02-06
4         C             2018-06-07      2013-09-13  2013-09-13
4         F             2018-06-07      2018-03-31  2018-04-05

(用于复制:

df = pd.DataFrame({'assigned': {0: pd.Timestamp('2015-07-02'), 1: '2015-09-10', 2: '2016-03-24', 3: '2013-10-21', 4: '2013-09-13', 5: '2018-03-31'},
                    'attorney': {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'C', 5: 'F'},
                    'cas_closed_date': {0: pd.Timestamp('2015-07-02'), 1: '2015-09-10', 2: '2016-03-24', 3: '2018-06-07', 4: '2018-06-07', 5: '2018-06-07'},
                    'case_nb': {0: 1, 1: 2, 2: 3, 3: 4, 4: 4, 5: 4},
                    'last_event': {0: pd.Timestamp('2015-07-02'), 1: '2015-09-10', 2: '2016-03-24', 3: '2014-02-06', 4: '2013-09-13', 5: '2018-04-05'}}

我的数据集包括案件编号,指派的律师,案件的结案日期,指派律师的日期以及该律师出现的最后事件。对于上面的示例,我希望最后一行是

4         F             2018-06-07      2018-03-31  2018-06-07

我已经看到了几种基于同一列中的数据来填充NA的方法,例如this question。但是这些方法使用transform,我无法使用多列。

到目前为止,我所能使用的是apply,但不适用于transform

def fixdate(gp):
    last_unasgn = gp.iloc[-1]['last_event']
    if gp.iloc[-1]['cas_closed_date'] > last_unasgn:
        return gp.iloc[-1]['cas_closed_date']
    else:
       return last_unasgn

asmt.groupby('evt_file_number').apply(lambda x: fixdate(x))
> 4  2018-06-07

是否可以使用transform?如果没有,使用汇总数据填充原始数据集的最佳方法是什么?

3 个答案:

答案 0 :(得分:1)

.transform操作将每个组的所有列作为一维序列传递给函数,而.apply操作将每个组的所有列作为DataFrame传递给函数。因此,.transform一次可处理一个Series(或列),而.apply则可处理整个DataFrame(或所有列)。希望这会有所帮助。

答案 1 :(得分:1)

如果同一天case_nb从未在同一天分配给两名不同的律师,则可以尝试此解决方案。

import numpy as np
import pandas as pd

df = pd.DataFrame({'assigned': {0: pd.Timestamp('2015-07-02'), 1: '2015-09-10',
                                2: '2016-03-24', 3: '2013-10-21', 4: '2013-09-13',
                                5: '2018-03-31'},
                    'attorney': {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'C', 5: 'F'},
                    'cas_closed_date': {0: pd.Timestamp('2015-07-02'), 1: '2015-09-10',
                                        2: '2016-03-24', 3: '2018-06-07', 4: '2018-06-07',
                                        5: '2018-06-07'},
                    'case_nb': {0: 1, 1: 2, 2: 3, 3: 4, 4: 4, 5: 4},
                    'last_event': {0: pd.Timestamp('2015-07-02'), 1: '2015-09-10',
                                   2: '2016-03-24', 3: '2014-02-06', 4: '2013-09-13',
                                   5: '2018-04-05'}})

out = df.groupby("case_nb")["assigned"].max().reset_index()
out["last"] = True
df = pd.merge(df, out, how="left", on= ["case_nb", "assigned"])
df["last_event"] = np.where(df["last"] == True, df["cas_closed_date"], df["last_event"])
del df["last"], out

也许有一个更优雅的解决方案,但是至少这是矢量的(请参见np.where),并且不要使用applypandas performaces

编辑:如果您想使用transform,此选项对我来说似乎是最快的解决方案。

df["last_assigned"] = df.groupby("case_nb")["assigned"].transform("max")
df["last_event"] = np.where(df["assigned"]==df["last_assigned"], 
                            df["cas_closed_date"],
                            df["last_event"])
del df["last_assigned"]

答案 2 :(得分:0)

我最终做了regex2和普通索引的组合。

transform