【问题标题】:Get the indices of the maximum value of each group获取每组最大值的索引
【发布时间】:2021-07-19 08:20:24
【问题描述】:

我有一个像这样的数据框df

df = pd.DataFrame(
    {
        "id": [101, 102, 102, 103, 201, 202, 202, 203],
        "type": ["A1", "B2", "B3", "A3", "A1", "B2", "B3", "A1"],
        "Val": np.random.randn(8),
    }
)

     id  type       value
0   101   A1    -0.238221
1   102   B2     1.051656
2   102   B3    -1.335417
3   102   A3     0.859323
4   201   A1    -0.819574
5   202   B2    -0.589278
6   202   B3     0.925917
7   203   A1    -0.044021

首先,我应用以下聚合来获取每个id 中的某个type

    idx = df.groupby("id")["type"].transform(lambda x: x.str.contains("B"))

    df[idx]
    
    id    type      value
1   102   B2     1.051656
2   102   B3    -1.335417
5   202   B2    -0.589278
6   202   B3     0.925917

现在,这是我的问题。我需要删除任何id 的所有记录,其中type 值不是最大值。最多,我的意思是有这个优先级:

An > Ak 其中 n > k。例如,对于id 102, B3 > B2,因此带有 B2 类型的行为 @ 987654329@ 102 应该被删除。请注意,对于任何 id,初始数据框不包含任何重复的 type 列。也就是说,不存在id为102的两个B2的情况。例如:

    id    type      value
1   102   B2     1.051656
2   102   B2    -1.335417

因此,对于任何id,我们不需要考虑type 列上的相等情况。

我试过的是这个;这给了我想要的最大值。

df[idx].groupby("id").max()
      type  value
id      
102   B3    1.051656
202   B3    0.925917

但是,我需要修改我的原始数据框df,以便删除除上述记录之外的任何其他记录。而我需要对任何type做这个操作 A,B,...Z 换句话说,我需要df最终看起来像这样。

     id  type       value
0   101   A1    -0.238221
2   102   B3    -1.335417
3   102   A3     0.859323
4   201   A1    -0.819574
6   202   B3     0.925917
7   203   A1    -0.044021

编辑:边缘案例

有一个特殊的typeBA。该类型的优先级确定如下:

BA type 值的可能性有限:zBAyBA

这里的优先级是 zBA > yBA

例如

     id  type       value
0   102   zBA    -0.238221
1   102   yBA     1.051656

输出

     id  type       value
0   102   zBA    -0.238221

【问题讨论】:

    标签: python pandas group-by aggregate


    【解决方案1】:

    您可以将字母和数字拉到单独的列中,对字母进行分组以获得最大数字,过滤数字并获得最终数据框:

     (df.assign(letter = df['type'].str[0], 
                number = df['type'].str[-1], 
                filt = lambda df: df.number.eq(df.groupby(['id', 'letter'])
                                                .number.transform('max')))
        .loc[lambda df: df.filt, df.columns])
    
        id type     value
    0  101   A1 -0.238221
    2  102   B3 -1.335417
    3  102   A3  0.859323
    4  201   A1 -0.819574
    6  202   B3  0.925917
    7  203   A1 -0.044021
    

    【讨论】:

    • 您好!这行得通,谢谢。我有一个快速的问题。 type 列上有一个极端情况,最后没有 number。所以,我正在为那个做字符串比较。例如,类型为U,该类型的优先级由前面的字母确定。例如,zU > yU。尽管如此,我相信我可以相应地映射该类型以适合您的解决方案,例如“zU”的“U2”和“yU”的“U1”。不过,我将不胜感激任何其他处理该边缘案例的方法。非常感谢!
    • 令人印象深刻。这是我需要学习的。
    • @zodiac645,你介意分享那个边缘案例吗?当我看到源数据和预期输出时,我的大脑工作得更好 - 然后解释点击(希望):)
    • 根据您的要求编辑,如果您有其他问题,请随时加入这里chat.stackoverflow.com/rooms/231589/…
    • 当有没有字母的列时,上面的代码片段将两行都取为相同的id,因为两个type值的“数字”相同,即A :)。我将只使用像{"yBA": "X1", "zBA", "X2"} 这样的字典并在type 列上执行替换作为解决方法。幸运的是,没有X 类型:)。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2019-05-09
    • 1970-01-01
    • 2021-08-25
    • 1970-01-01
    • 2016-07-09
    • 1970-01-01
    • 2022-11-10
    • 2013-07-11
    相关资源
    最近更新 更多