Как удалить столбцы, которые имеют одинаковые значения во всех строках через pandas или spark dataframe?

предположим я примерно следующее:

  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

как мы можем отбросить все эти столбцы как (value, value2, value3), где все строки имеют одинаковые значения, в одной команде или паре команд с помощью python ?

рассмотрим, что у нас есть много столбцов, похожих на value,value2,value3...value200.

выход:

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

2 ответов


что мы можем сделать, это apply nunique чтобы вычислить количество уникальных значений в df и удалить столбцы, которые имеют только одно уникальное значение:

In [285]:
cols = list(df)
nunique = df.apply(pd.Series.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 числовые столбцы и sums них:

In [298]:
cols = df.select_dtypes([np.number]).columns
diff = df[cols].diff().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

другое решение -set_index из столбца, которые не сравниваются, а затем сравните первую строку, выбранную iloc by 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