Как удалить столбцы, которые имеют одинаковые значения во всех строках через 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