根据分组后各组中最后一个值的内容对列的总和计数

时间:2019-12-18 08:53:11

标签: python pandas pandas-groupby

我的数据框如下

id       val    type
aa         0    C
aa         1    T
aa         2    T
aa         3    T
aa         0    M
aa         1    M
aa         2    C
aa         3    M
bbb        0    C
bbb        1    T
bbb        2    T
bbb        3    T
bbb        0    M
bbb        1    M
bbb        2    C
bbb        3    T
cccccc     0    C
cccccc     1    T
cccccc     2    T
cccccc     3    T
cccccc     0    M
cccccc     1    M
cccccc     0    C
cccccc     1    C

我想先做一个groupby“ ID”,然后再做sumcount列“ val”中的行,但是应该加起来的行只是包含以下内容的行“类型”与每个组中“类型”列的最后一个值相同。

例如,组的最后一行具有“类型” M,因此仅对组中具有“类型” M的行进行求和和计数。因此,需要将值0、1和3相加,并且计数为3。

上述df的预期输出如下。输出中的“类型”列不是必需的,如果花费更多时间可以将其忽略。我在这里展示它只是为了让我更清楚地说明要实现的目标。

id     val  count   type
aa       4  3       M
bbb      9  4       T
cccccc   1  3       C

2 个答案:

答案 0 :(得分:2)

使用GroupBy.transformlast进行过滤,然后通过命名聚合进行聚合,适用于0.25+的熊猫:

df = (df[df['type'].eq(df.groupby('id')['type'].transform('last'))]
            .groupby('id').agg(val=('val', 'sum'), 
                               count=('val', 'size'), 
                               type=('type','last')))
print (df)
        val  count type
id                     
aa        4      3    M
bbb       9      4    T
cccccc    1      3    C

Series.mapDataFrame.drop_duplicates创建的系列DataFrame.set_index的另一种解决方案:

s = df.drop_duplicates('id', keep='last').set_index('id')['type']
df = (df[df['type'].eq(df['id'].map(s))]
            .groupby('id').agg(val=('val', 'sum'), 
                               count=('val', 'size'), 
                               type=('type','last')))
print (df)
        val  count type
id                     
aa        4      3    M
bbb       9      4    T
cccccc    1      3    C

答案 1 :(得分:1)

# find the last type by group
last_type = df[["id", "type"]].groupby("id").tail(1)


df['count'] = 1

# inner merge with the last type (i.e. keep only the last type by group)
df.merge(last_type, on=["id", "type"], how="inner").groupby(["id", "type"]).agg({'val':'sum', 'count': 'sum'}).reset_index()

输出

       id type  val  count
0      aa    M    4      3
1     bbb    T    9      4
2  cccccc    C    1      3