2016-09-23 39 views
7

Załóżmy mam dane podobne do następujących:Jak upuścić kolumny, które mają te same wartości we wszystkich wierszach, za pośrednictwem pand lub iskiernika?

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 

Jak możemy upuścić wszystkie te kolumny jak (value, value2, value3) gdzie wszystkie wiersze mają takie same wartości, w jednym poleceniu lub kilku poleceń za pomocą pytona?

Uważamy, że mamy wiele kolumn podobnych do value, value2, value3 ... value200.

wyjściowa:

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

Masz na myśli 'df.drop_duplicates (podzbiór = ['wartość', 'wartość2', 'wartość3'])'? – EdChum

+0

załóżmy, że mamy wiele kolumn, jak około 200 –

Odpowiedz

13

Co możemy zrobić, to applynunique calc liczbę unikalnych wartości w df i upuść kolumny, które mają tylko jeden unikalną wartość:

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 

Innym jest tylko diff kolumn numerycznych i sums je:

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 

Innym podejściem jest zastosowanie własności, że odchylenie standardowe wynosi zero dla kolumny o tej samej wartości:

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 

rzeczywistości powyżej mogą być wykonane w jednej wkładki:

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 
+0

cześć dzięki za odpowiedź, ale miałem na myśli, całkowicie upuść tylko te kolumny i wszystkie pozostałe wiersze nienaruszone, i rozważ duże nie. kolumn takich jak value, value2 ... value 200, również zaktualizuję pytanie. –

+0

@ EdChum zaktualizowałem pytanie, czy możesz rzucić okiem? –

+0

OK Rozumiem, co chcesz zobaczyć Aktualizacja – EdChum

3

Innym rozwiązaniem jest set_index z kolumny, które nie są zestawiane i następnie porównanie pierwszego rzędu wybrany przez iloc przez eq wszelkich DataFrame i ostatniego użycia 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 
+0

Myślę, że twoja odpowiedź może być poprawiona przez odfiltrowanie kolumn nieliczbowych, tak jak zrobiłem to w mojej odpowiedzi, ponieważ rzeczywiste dane OP mogą zawierać wiele nie-numerycznych kolumn – EdChum

+0

@EdChum - Tak, masz rację. – jezrael