【问题标题】:Pandas row filtering on multiple columnsPandas 在多列上进行行过滤
【发布时间】:2021-08-27 09:53:55
【问题描述】:

我正在尝试过滤以下 pandas 数据框。

    id        X_1      X_2    X_4     M_1       M_2     M_3 
0    i24     Nan     0.27     Nan     0.20     0.25    0.27 
1    i25     0.45    0.47     0.46    0.42     Nan     0.42  
2    i11     Nan     Nan      0.32    0.32     0.35    0.29    
3    i47     Nan     0.56     0.59     Nan     0.56    0.51 

特别是,我想分别处理 M_ 列和 X_columns 并仅保留对于每个“组”M 和 X 至少具有两个非 Nan 值的条目。 例如。不应包含条目 i24,因为它在 X_1 和 X_4 中的值都是 Nan,在 X“组”中只留下一个正确的值。应该保留 i25 和 i47,因为它们尊重约束。

感谢任何可以提供帮助的人。

【问题讨论】:

    标签: python pandas dataframe statistics


    【解决方案1】:
    ndf = df.set_index("id")
    good_rows = (ndf.groupby(lambda col: col.split("_", maxsplit=1)[0], axis=1)
                    .count()
                    .ge(2)
                    .all(axis=1))
    ndf = ndf.loc[good_rows]
    

    我们首先将id 设置为索引以将其放在一边。然后按列名分组,直到第一个 _ 然后计算非 NaN 值。如果 X 和 M 的计数都大于或等于 2,我们称之为好行。然后用这些行索引,

    得到

    >>> ndf
    
          X_1   X_2   X_4   M_1   M_2   M_3
    id
    i25  0.45  0.47  0.46  0.42   NaN  0.42
    i47   NaN  0.56  0.59   NaN  0.56  0.51
    

    请注意,这假设这些值为NaNs;如果不是字符串,那么请事先这样做:

    df = df.replace("Nan", np.nan)
    

    【讨论】:

      【解决方案2】:

      您可以先分离出X 列和M 列的列表,然后使用apply 并检查两个列组是否满足小于2 个NaN 值的条件,然后相应地创建掩码,最后使用掩码得到所需的结果。

      xCols = [col for col in df if col.startswith('X')]  # ['X_1', 'X_2', 'X_4']
      mCols = [col for col in df if col.startswith('M')]  # ['M_1', 'M_2', 'M_3']
      
      df[df.apply(lambda row: sum(row[mCols].isna())<2 and sum(row[xCols].isna())<2, axis=1)]
      

      输出:

          id   X_1   X_2   X_4   M_1   M_2   M_3
      1  i25  0.45  0.47  0.46  0.42   NaN  0.42
      3  i47   NaN  0.56  0.59   NaN  0.56  0.51
      

      【讨论】:

        猜你喜欢
        • 2021-12-06
        • 1970-01-01
        • 2021-05-15
        • 2017-09-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多