【问题标题】:Select particular rows from inside groups in pandas dataframe从熊猫数据框中的组内选择特定行
【发布时间】:2015-12-03 14:32:20
【问题描述】:

假设我有一个如下所示的数据框:

   group  level
0      1     10
1      1     10
2      1     11
3      2      5
4      2      5
5      3      9
6      3      9
7      3      9
8      3      8

想要的输出是这样的:

   group  level
0      1     10
5      3      9

也就是说,这就是逻辑:查看每个组的内部,如果level 列中存在多个不同的值,则返回该组中的第一行。例如,没有选择组 2 中的任何行,因为 level 列中存在的唯一值是 5

另外,如果我想要最后一行而不是第一行这样的组,情况会如何变化?

我尝试将group_by 语句与从level 列中的条目创建集合相结合,但未能产生任何几乎合理的结果。

【问题讨论】:

    标签: python pandas indexing group-by dataframe


    【解决方案1】:

    这可以通过groupbyapply 在每个组上运行一个简单的函数来完成:

    def get_first_val(group):
        has_multiple_vals = len(group['level'].unique()) >= 2
        if has_multiple_vals:
            return group['level'].loc[group['level'].first_valid_index()]
        else:
            return None
    
    df.groupby('group').apply(get_first_val).dropna()
    Out[8]: 
    group
    1    10
    3     9
    dtype: float64
    

    还有一个last_valid_index() 方法,所以你不必 进行任何重大更改以获取最后一行。

    如果您想保留其他列,只需稍作调整:

    import numpy as np
    df['col1'] = np.random.randint(10, 20, 9)
    df['col2'] = np.random.randint(20, 30, 9)
    df
    Out[17]: 
       group  level  col1  col2
    0      1     10    19    21
    1      1     10    18    24
    2      1     11    14    23
    3      2      5    14    26
    4      2      5    10    22
    5      3      9    13    27
    6      3      9    16    20
    7      3      9    18    26
    8      3      8    11    2
    
    def get_first_val_keep_cols(group):
        has_multiple_vals = len(group['level'].unique()) >= 2
        if has_multiple_vals:
            return group.loc[group['level'].first_valid_index(), :]
        else:
            return None
    
    df.groupby('group').apply(get_first_val_keep_cols).dropna()
    Out[20]: 
           group  level  col1  col2
    group                          
    1          1     10    19    21
    3          3      9    13    27
    

    【讨论】:

    • 如何确保其他列得到维护,假设原始数据框有 col1、col2、col3,我仍希望将其保留为结果的一部分?
    • 这神秘地不适用于我。使用以前的方法,我得到了正确的结果,只丢失了一些列,现在我得到了一个空的数据框。也许这里返回 group.loc[group['level'].first_valid_index(), :] without , ?
    【解决方案2】:

    这样会更简单:

    In [121]:
    
    print df.groupby('group').\
              agg(lambda x: x.values[0] if (x.values!=x.values[0]).any() else np.nan).\
               dropna()
    
           level
    group       
    1         10
    3          9
    

    对于每个组,如果任何值与第一个值不同,则将该组聚合为其第一个值;否则,将其聚合到nan

    最后,dropna()

    【讨论】:

      猜你喜欢
      • 2022-01-21
      • 1970-01-01
      • 2018-05-20
      • 2021-07-17
      • 2018-03-13
      • 2015-03-29
      • 2017-06-30
      • 2013-11-09
      • 2021-07-15
      相关资源
      最近更新 更多