【问题标题】:How can I remove features/columns of a data frame if at least 20% of their entries take a specific value, using pandas/numpy?如果至少 20% 的条目具有特定值,如何使用 pandas/numpy 删除数据框的特征/列?
【发布时间】:2019-10-24 22:50:04
【问题描述】:

我正在使用 pandas 和 numpy。

我想删除我的 9000 x 13 训练数据框中至少 20% 的条目取值 -200 的每一列。在这种情况下,-200 就像一个缺失值或 NaN,所以我要删除无用的变量。我有下面的数据样本。任何帮助,将不胜感激。 这是某种尝试: train_mod = train.loc[:, train.isnull().mean() <.2]

A        B        C            D      E                 F          \
5723     0.5       846.25      -200    2.619270         627.50     79.0   
4014     1.5      1016.25      -200    6.810175         848.50     99.0   
4074     2.0      -200.00      -200    -200.000        -200.00    114.0   
4577     1.6       950.50      -200    8.649763         925.50    351.0   
6691     4.7      1469.75      -200   25.820425        1449.75    677.0   
2889     0.5       902.50      -200    2.676091         631.25   -200.0   
4387     2.0      1095.75      -200   12.972673        1082.75    310.0   
4289     1.0       885.50      -200    2.695146         632.50   -200.0   
2887     2.3      1355.00      -200   16.611225        1198.25    129.0   
5694     1.1       936.25      -200    6.821513         849.00    127.0   

【问题讨论】:

标签: python pandas numpy dataframe


【解决方案1】:

您可以尝试使用numpy.where() 创建一个新的"tagging_column"。然后使用它在groupby 中创建一个计数列,然后按计数进行聚合。然后最后计算比率。如果比率为>=20%,则删除所有标记为minus 200 or lower value

考虑:

>>> df = pd.DataFrame({'id':[1,2,3,4,5,6,7,8,9], 'val':[100,200,-250,2000,20312039,12485,-300,-350,-60494]})
>>> df
   id       val
0   1       100
1   2       200
2   3      -250
3   4      2000
4   5  20312039
5   6     12485
6   7      -300
7   8      -350
8   9    -60494

>>> df['Check Negative 200'] = np.where(df['val'] <=-200, ['Negative 200 or lower'], ['Greater than -200'])
>>> df
   id       val     Check Negative 200  Count
0   1       100      Greater than -200      5
1   2       200      Greater than -200      5
2   3      -250  Negative 200 or lower      4
3   4      2000      Greater than -200      5
4   5  20312039      Greater than -200      5
5   6     12485      Greater than -200      5
6   7      -300  Negative 200 or lower      4
7   8      -350  Negative 200 or lower      4
8   9    -60494  Negative 200 or lower      4

>>> df['Count'] = df.groupby('Check Negative 200')['Check Negative 200'].transform('count')
>>> df
   id       val     Check Negative 200  Count
0   1       100      Greater than -200      5
1   2       200      Greater than -200      5
2   3      -250  Negative 200 or lower      4
3   4      2000      Greater than -200      5
4   5  20312039      Greater than -200      5
5   6     12485      Greater than -200      5
6   7      -300  Negative 200 or lower      4
7   8      -350  Negative 200 or lower      4
8   9    -60494  Negative 200 or lower      4

>>> dd = dict(df['Check Negative 200'].value_counts())
>>> dd
{'Greater than -200': 5, 'Negative 200 or lower': 4}

if dd['Negative 200 or lower']/len(df) > .2:
    df = df[df['Check Negative 200'].isin(['Greater than -200'])]
else:
    pass

>>> df
   id       val Check Negative 200  Count
0   1       100  Greater than -200      5
1   2       200  Greater than -200      5
3   4      2000  Greater than -200      5
4   5  20312039  Greater than -200      5
5   6     12485  Greater than -200      5

您还可以删除添加的列,以便您的列与输入保持相同。

>>> del df['Check Negative 200']
>>> del df['Count']
>>> df.reset_index(inplace = True, drop = True)
>>> df
   id       val
0   1       100
1   2       200
2   4      2000
3   5  20312039
4   6     12485

【讨论】:

    【解决方案2】:

    这是一个有点复杂的单行代码,应该可以解决问题:

    df_mod = df[df.columns[(df == -200).sum()/df.shape[0] < 0.2]]
    

    基本上,从内到外,我们看到每列中有多少值是无效的 (df == -200)。该括号上的总和是布尔值的总和,因此它计算 True 条目。我们将其除以行数,如果该值小于 20%,则保留列。然后,我们获取满足此条件的列的 DataFrame,并留下少于 20% 的条目无效的列。

    希望这会有所帮助!

    【讨论】:

      【解决方案3】:
      val = -200
      rows_20 = df.shape[0] // 5
      
      train_mod = train[[c for c in train.columns if (train[c] == val).sum() <= rows_20]]
      

      解释:

      train[c] == val 返回一系列布尔值(真/假)。对此调用 .sum() 会计算“真”值的数量。然后根据 row_20 进行检查,这是 DataFrame 中行数的 20%。

      列表推导仅返回与if 条件匹配的列。

      【讨论】:

      • 仅代码的答案在本网站上通常不受欢迎。您能否编辑您的答案以包含一些 cmets 或对您的代码的解释?解释应该回答这样的问题:它有什么作用?它是如何做到的?它去哪儿了?它如何解决OP的问题?请参阅:How to anwser。谢谢!
      • @EduardoBaitello 很公平,尽管该链接没有提及任何关于代码仅答案的内容
      猜你喜欢
      • 2016-12-19
      • 1970-01-01
      • 2020-05-28
      • 2018-08-23
      • 1970-01-01
      • 2018-01-13
      • 2022-01-22
      • 1970-01-01
      • 2021-11-11
      相关资源
      最近更新 更多