【问题标题】:How to drop columns which have same values in all rows via pandas or spark dataframe?如何通过熊猫或火花数据框删除所有行中具有相同值的列?
【发布时间】:2016-09-23 10:30:25
【问题描述】:

假设我有类似以下的数据:

  index id   name  value  value2  value3  data1  val5
    0  345  name1    1      99      23     3      66
    1   12  name2    1      99      23     2      66
    5    2  name6    1      99      23     7      66

我们如何使用 python 在一个或多个命令中删除所有行具有相同值的所有列,例如 (value、value2、value3)?

假设我们有许多列类似于value、value2、value3...value200。

输出:

   index    id  name   data1
       0   345  name1    3
       1    12  name2    2
       5     2  name6    7

【问题讨论】:

    标签: python pandas apache-spark-sql duplicates multiple-columns


    【解决方案1】:

    我们可以做的是使用nunique计算数据框每一列中唯一值的数量,并删除只有一个唯一值的列:

    In [285]:
    nunique = df.nunique()
    cols_to_drop = nunique[nunique == 1].index
    df.drop(cols_to_drop, axis=1)
    
    Out[285]:
       index   id   name  data1
    0      0  345  name1      3
    1      1   12  name2      2
    2      5    2  name6      7
    

    另一种方法是只使用diff 数字列,取abs 值和sums 它们:

    In [298]:
    cols = df.select_dtypes([np.number]).columns
    diff = df[cols].diff().abs().sum()
    df.drop(diff[diff== 0].index, axis=1)
    ​
    Out[298]:
       index   id   name  data1
    0      0  345  name1      3
    1      1   12  name2      2
    2      5    2  name6      7
    

    另一种方法是使用具有相同值的列的标准差为零的属性:

    In [300]:
    cols = df.select_dtypes([np.number]).columns
    std = df[cols].std()
    cols_to_drop = std[std==0].index
    df.drop(cols_to_drop, axis=1)
    
    Out[300]:
       index   id   name  data1
    0      0  345  name1      3
    1      1   12  name2      2
    2      5    2  name6      7
    

    其实以上都可以单行完成:

    In [306]:
    df.drop(df.std()[(df.std() == 0)].index, axis=1)
    
    Out[306]:
       index   id   name  data1
    0      0  345  name1      3
    1      1   12  name2      2
    2      5    2  name6      7
    

    【讨论】:

    • 警告:按唯一条目数删除列==1 最终会删除只有一个非 NAN 条目的列。这可能是也可能不是意图。
    • 有人可以帮助如何删除具有 95% 相同值的列
    【解决方案2】:

    一个简单的单行(python):

    df=df[[i for i in df if len(set(df[i]))>1]]
    

    【讨论】:

    • 很好的答案!替代方案是:df = df[[i for i in df if df[i].nunique()>1]]
    【解决方案3】:

    另一种解决方案是 set_index 来自未比较的列,然后将 iloc 选择的第一行与 eq 与所有 DataFrame 和最后使用 boolean indexing 进行比较:

    df1 = df.set_index(['index','id','name',])
    print (~df1.eq(df1.iloc[0]).all())
    value     False
    value2    False
    value3    False
    data1      True
    val5      False
    dtype: bool
    
    print (df1.ix[:, (~df1.eq(df1.iloc[0]).all())].reset_index())
       index   id   name  data1
    0      0  345  name1      3
    1      1   12  name2      2
    2      5    2  name6      7
    

    【讨论】:

      【解决方案4】:

      pythonic 解决方案

      原始数据帧

      index id   name  value  value2  value3  data1  val5
          0  345  name1    1      99      23     3      66
          1   12  name2    1      99      23     2      66
          5    2  name6    1      99      23     7      66
      

      解决方案

      for col in df.columns:  # Loop through columns
        if len(df[col].unique()) == 1:  # Find unique values in column along with their length and if len is == 1 then it contains same values
          df.drop([col], axis=1, inplace=True)  # Drop the column
      

      执行上述代码后的数据帧

         index   id   name  data1
      0      0  345  name1      3
      1      1   12  name2      2
      2      5    2  name6      7
      

      【讨论】:

        【解决方案5】:

        您可以使用nunique(),它返回每列中唯一值的数量:

        df[df.columns[df.nunique() > 1]]
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-01-07
          • 2019-11-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-01-28
          • 1970-01-01
          相关资源
          最近更新 更多