代码之家  ›  专栏  ›  技术社区  ›  VERBOSE

如何根据两个条件删除每组中不需要的行?

  •  0
  • VERBOSE  · 技术社区  · 2 年前

    我的输入是一个数据帧:

    df = pd.DataFrame({'col1': ['A', 'A', 'B', 'C', 'D', 'D', 'D', 'E', 'E'],
     'col2': ['x1', 'x2', 'x1', 'x1', 'x1', 'x2', 'x3', 'x1', 'x2'],
     'col3': ['', 'mssg1', 'mssg2', '', 'mssg3', '', 'mssg4', '', '']})
    
      col1 col2   col3
    0    A   x1       
    1    A   x2  mssg1
    2    B   x1  mssg2
    3    C   x1       
    4    D   x1  mssg3
    5    D   x2       
    6    D   x3  mssg4
    7    E   x1       
    8    E   x2       
    

    我需要循环浏览列中的每组 col1 看看它是否重复,如果为True,请检查该列 col3 并且仅保留非空值。如果所有值都为空,则保留所有值。

    为此,我制作了以下代码。乍一看,它是有效的,但它不仅在我的真实数据集上很慢,而且如果它在逻辑中遗漏了什么,我也会忽略它。

    def clean(x):
        if len(x) > 1 and x['col3'].notna().any():
            return x.loc[x['col3'].notna()]
        else:
            return x
    
    final = df.replace('', None).groupby('col1', as_index=False).apply(clean).droplevel(0).fillna('')
    

    我的预期输出是:

    
      col1 col2   col3
    1    A   x2  mssg1
    2    B   x1  mssg2
    3    C   x1       
    4    D   x1  mssg3
    6    D   x3  mssg4
    7    E   x1       
    8    E   x2       
    

    你们能告诉我如何解决我的问题吗?

    2 回复  |  直到 2 年前
        1
  •  1
  •   mozway    2 年前

    使用布尔索引:

    # is col3 not empty?
    m1 = df['col3'].ne('')
    # is m1 not all True per col1?
    m2 = ~m1.groupby(df['col1']).transform('any')
    
    out = df[m1|m2]
    

    输出:

      col1 col2   col3
    1    A   x2  mssg1
    2    B   x1  mssg2
    3    C   x1       
    4    D   x1  mssg3
    6    D   x3  mssg4
    7    E   x1       
    8    E   x2       
    
        2
  •  1
  •   Panda Kim    2 年前

    密码

    如果df的col3不是“”,或者当df按col1分组时,组中col3的所有值都是“”,则保留它

    cond1 = df['col3'].eq('')
    cond2 = cond1.groupby(df['col1']).transform(all)
    out = df[~cond1 | cond2]
    

    输出:

        col1    col2    col3
    1   A       x2      mssg1
    2   B       x1      mssg2
    3   C       x1  
    4   D       x1      mssg3
    6   D       x3      mssg4
    7   E       x1  
    8   E       x2