2016-11-08 13 views
0

すべての行に同じ値を持ついくつかの列を持つPandas DataFrameがあります。同じ値を含むPandas DataFrameの列を削除する方法

だから、のようなもの: -

Col1 Col2  Col3 .... ColX ColY ColZ 
323  False 324   4 abc Sync 
232  False 342   4 def Sync 
364  False 2343   4 ghi Sync 

だから私は上記のデータフレームからCol2に、COLXとColZをドロップしたいと思います。

答えて

6

あなたは、特定の行に対してデータフレームを比較する(私はdf.iloc[0]で最初のものを選んだ)、あなたが指定した条件を満足する列を選択するlocを使用することができます。

df.loc[:, ~(df == df.iloc[0]).all()] 
Out: 
    Col1 Col3 ColY 
0 323 324 abc 
1 232 342 def 
2 364 2343 ghi 

タイミング:

@root's suggestionnuniqueは、Seriesを単一の値と比較するよりもかなり高速です。 @MMF suggestedがより効率的なアプローチのように見えるので、あなたが膨大な数のカラム(例えば、何千もの)をカラムに対して反復しない限り。

df = pd.concat([df]*10**5, ignore_index=True) 

%timeit df.loc[:, ~(df == df.iloc[0]).all()] 
1 loop, best of 3: 377 ms per loop 

%timeit df[[col for col in df if not df[col].nunique()==1]] 
10 loops, best of 3: 35.6 ms per loop 


df = pd.concat([df]*10, axis=1, ignore_index=True) 

%timeit df.loc[:, ~(df == df.iloc[0]).all()] 
1 loop, best of 3: 3.71 s per loop 

%timeit df[[col for col in df if not df[col].nunique()==1]] 
1 loop, best of 3: 353 ms per loop 


df = pd.concat([df]*3, axis=1, ignore_index=True) 

%timeit df.loc[:, ~(df == df.iloc[0]).all()] 
1 loop, best of 3: 11.3 s per loop 

%timeit df[[col for col in df if not df[col].nunique()==1]] 
1 loop, best of 3: 1.06 s per loop 
+0

作品を!解決済み。 – xkcd

+0

大きなDFのタイミング比較を追加できますか?私の野生の推測 - あなたの解決策はより速くなるでしょう... – MaxU

+1

@マックス:私のタイミングから、他の解決策は速いです。 – root

5

また、各列の値によって生成されたセットの長さをチェックこれを行うことができます。魔法のように

df = df[[col for col in df if not len(set(df[col]))==1]] 
+2

FYI、 'df [col] .nunique()== 1は' len(set(df [col]))== 1 'より高速です。 – root

+0

いくつかの列が同じ値を持っていて、大きなデータフレームの場合は最初の2つまたは3つの連続した列の値を比較するだけで、列全体を削除するのに十分です。なぜ列全体をチェックする必要がありますか? –

+0

@rootありがとう;) – MMF

関連する問題