【问题标题】:How to delete rows with 51%+ NaN values based on count from another column如何根据另一列的计数删除具有 51%+ NaN 值的行
【发布时间】:2019-11-05 15:38:00
【问题描述】:

我想删除目标值超过 25% 的时间为空的行,并将 25% 的条件应用于另一列。或者,我可以提出一个阈值,作为 NaN 可接受的最大次数,但再次基于另一列的值。

我的目标是在有足够多的观察值时根据另一列按组估算值,并且如果未达到阈值,则删除这些观察值。

我的数据框要大得多,但它是这样的 - 假设 col['aid'] 对应的 'a3' 值的 50% 在 col['T'] 中为空

df = pd.DataFrame([[1,'a1','c1', 111],
                   [2,'a2','c3', 222],
                   [3,'a3','c3',],
                   [4,'a1','c5', 444],
                   [5,'a3','c4',],
                   [6,'a3','c5', 666],
                   [7,'a3','c3', 777]], columns=['pid','aid','cid','T'])
df
   pid aid cid      T
0    1  a1  c1  111.0
1    2  a2  c3  222.0
2    3  a3  c3    NaN
3    4  a1  c5  444.0
4    5  a3  c4    NaN
5    6  a3  c5  666.0
6    7  a3  c3  777.0

我试过了

df.dropna(thresh=0.25*(df['aid'].value_counts()), axis = 1)

我想要的输出在 25% 的阈值是

   pid aid cid      T
0    1  a1  c1  111.0
1    2  a2  c3  222.0
3    4  a1  c5  444.0
5    6  a3  c5  666.0
6    7  a3  c3  777.0

在 51% 的阈值时,我的数据框将保持不变

   pid aid cid      T
0    1  a1  c1  111.0
1    2  a2  c3  222.0
2    3  a3  c3    NaN
3    4  a1  c5  444.0
4    5  a3  c4    NaN
5    6  a3  c5  666.0
6    7  a3  c3  777.0

任何建议将不胜感激

【问题讨论】:

    标签: python python-3.x pandas


    【解决方案1】:

    您可以使用transform

    s=df['T'].isnull().groupby(df['aid']).transform('mean')
    n=0.25
    df.loc[(s<=n)|(df['T'].notnull()),]
    Out[39]: 
       pid aid cid      T
    0    1  a1  c1  111.0
    1    2  a2  c3  222.0
    3    4  a1  c5  444.0
    5    6  a3  c5  666.0
    6    7  a3  c3  777.0
    

    【讨论】:

      【解决方案2】:

      我愿意

      thresh = .50
      if len(df.query("aid=='a3' and T != T").index) / len(df.index) > thresh:
          df = df.dropna(subset=['T'])
      

      或者如果你不喜欢查询语法,

      thresh = .50
      if len(df[(df['aid'] == 'a3') & (df['T'].isna())].index) / len(df.index) > thresh:
          df = df.dropna(subset=['T'])
      

      最大计数版本:

      maxcount = 2
      if len(df[(df['aid'] == 'a3') & (df['T'].isna())].index) > maxcount:
          df = df.dropna(subset=['T'])
      

      [编辑] 由于我没有足够的代表来评论 WeNYoBen 的回答,这里是他们的回答的 maxcount 版本,带有更多的 Pythonic 变量名称:

      aid_var_null_ct = df['T'].isnull().groupby(df['aid']).transform('sum')
      thresh = 1
      df.loc[(aid_var_null_ct <= thresh) | (df['T'].notnull()),]
      

      【讨论】:

      • 这可行,但它需要我知道值'a3'。实际数据集很大,所以我需要按照 WeNYoBen 的建议按列分组
      • 谢谢,不知道您是否想要特定的列值或任何值。
      最近更新 更多