2013-11-26 10 views
14

Ich habe einen Datenrahmen, der Spalten haben kann oder nicht, die den gleichen Wert haben. Zum BeispielPanda Datenrahmen entfernen Konstante Spalte

row A B 
    1  9 0 
    2  7 0 
    3  5 0 
    4  2 0 

würde ich zurückkehren möchte nur

row A 
    1  9  
    2  7  
    3  5  
    4  2 

Gibt es eine einfache Art und Weise zu identifizieren, wenn eine dieser Spalten vorhanden sind und sie dann entfernen?

Antwort

20

Ich glaube, diese Option wird schneller sein als die anderen Antworten hier, da es nur einmal, um den Datenrahmen durchlaufen wird für den Vergleich und Kurzschluss, wenn ein nicht-eindeutigen Wert gefunden wird.

>>> df 

    0 1 2 
0 1 9 0 
1 2 7 0 
2 3 7 0 

>>> df.loc[:, (df != df.iloc[0]).any()] 

    0 1 
0 1 9 
1 2 7 
2 3 7 
+2

Aargh zu: '<>'. –

+0

@AndyHayden Pascal Gewohnheiten sterben schwer. Ich habe es geändert. – chthonicdaemon

+0

+1 danke für die Änderung. Dies schließt die Any-Schaltung kurz, nachdem es bereits den! = Vergleich für jedes Element durchgeführt hat, so dass die Lösung von DSM wahrscheinlich effizienter sein wird ... frage mich, ob es eine bessere Kurzschlusslösung gibt. –

13

Ignorieren NaN s wie üblich, ist eine Spalte konstant, wenn nunique() == 1. Also:

>>> df 
    A B row 
0 9 0 1 
1 7 0 2 
2 5 0 3 
3 2 0 4 
>>> df = df.loc[:,df.apply(pd.Series.nunique) != 1] 
>>> df 
    A row 
0 9 1 
1 7 2 
2 5 3 
3 2 4 
+0

'df.apply (pd.Series.nunique)' ist einfacher 'df.nunique()', zumindest in Pandas 0.20.3. – EOL

+0

Und wenn wir wollen, dass NaN als ein eindeutiger Wert betrachtet wird, funktioniert 'df.nunique (dropna = False)' gut (es behandelt die Tatsache, dass NaN ∈ NaN wie wir erwarten, alle NaN-Werte als denselben Wert zählend, obwohl sie sind nicht gleich). – EOL

2

Unter der Annahme, dass der Datenrahmen vollständig vom Typ numerisch ist:

Sie versuchen können:

>>> df = df.loc[:, df.var() == 0.0] 

die entfernen konstante Spalten (d Varianz = 0.).

Wenn der Datenrahmen des Typs sowohl numerische als auch Objekt, versuchen Sie sollten dann:

>>> enum_df = df.select_dtypes(include=['object']) 
>>> num_df = df.select_dtypes(exclude=['object']) 
>>> num_df = num_df.loc[:, num_df.var() == 0.0] 
>>> df = pd.concat([num_df, enum_df], axis=1) 

die konstante Spalten von nur numerischen Typ sinkt.

Wenn Sie wollen auch konstant Enum Spalten ignorieren/löschen, sollten Sie versuchen:

>>> enum_df = df.select_dtypes(include=['object']) 
>>> num_df = df.select_dtypes(exclude=['object']) 
>>> enum_df = enum_df.loc[:, [True if y !=1 else False for y in [len(np.unique(x, return_counts=True)[-1]) for x in enum_df.T.as_matrix()]]] 
>>> num_df = num_df.loc[:, num_df.var() == 0.0] 
>>> df = pd.concat([num_df, enum_df], axis=1) 
+0

Vermutlich möchten Sie 'df = df.loc [:, ~ df.var() == 0.0]' sonst wählen Sie die 0 Spalten. Es ist wahrscheinlich auch wert, 'np.isclose (0, df.var())' für mögliche Gleitkommafehler zu machen – jeremycg

0

Hier ist meine Lösung ist, da ich sowohl Objekt und numerische Spalten tun musste. Nicht behauptet, es sei super effizient oder irgendetwas anderes, aber es macht die Arbeit erledigt.

Zusätzliche Einschränkung, es wird nicht auf Spalten von Listen oder Arrays arbeiten, da sie nicht hashbar sind.

Verwandte Themen