2015-10-15 57 views
3

有沒有更快的方式來刪除只包含一個不同的值比下面的代碼的列?快速刪除只有一個不同值的數據幀列

cols=df.columns.tolist() 
for col in cols: 
    if len(set(df[col].tolist()))<2: 
     df=df.drop(col, axis=1) 

這對於大型數據幀來說確實很慢。從邏輯上講,這樣可以計算每列中值的數量,實際上它可以在達到2個不同值後停止計數。

+0

密切相關:https://stackoverflow.com/q/20209600/671013 – Dror

回答

3

您可以使用Series.unique()方法找出列中的所有唯一元素,以及.unique()僅返回1元素的列,您可以刪除該元素。實施例 -

for col in df.columns: 
    if len(df[col].unique()) == 1: 
     df.drop(col,inplace=True,axis=1) 

不做就地滴的方法 -

res = df 
for col in df.columns: 
    if len(df[col].unique()) == 1: 
     res = res.drop(col,axis=1) 

演示 -

In [154]: df = pd.DataFrame([[1,2,3],[1,3,3],[1,2,3]]) 

In [155]: for col in df.columns: 
    .....:  if len(df[col].unique()) == 1: 
    .....:   df.drop(col,inplace=True,axis=1) 
    .....: 

In [156]: df 
Out[156]: 
    1 
0 2 
1 3 
2 2 

定時結果 -

In [166]: %paste 
def func1(df): 
     res = df 
     for col in df.columns: 
       if len(df[col].unique()) == 1: 
         res = res.drop(col,axis=1) 
     return res 

## -- End pasted text -- 

In [172]: df = pd.DataFrame({'a':1, 'b':np.arange(5), 'c':[0,0,2,2,2]}) 

In [178]: %timeit func1(df) 
1000 loops, best of 3: 1.05 ms per loop 

In [180]: %timeit df[df.apply(pd.Series.value_counts).dropna(thresh=2, axis=1).columns] 
100 loops, best of 3: 8.81 ms per loop 

In [181]: %timeit df.apply(pd.Series.value_counts).dropna(thresh=2, axis=1) 
100 loops, best of 3: 5.81 ms per loop 

最快的方法似乎仍然是使用unique並遍歷列的方法。

2

你可以通過調用apply創建DF的面具,並調用value_counts,這將產生NaN所有行除一人外,你可以調用dropna逐列,並通過PARAM thresh=2所以必須有2個或更多的非 - NaN值:從布爾條件

In [329]: 
df = pd.DataFrame({'a':1, 'b':np.arange(5), 'c':[0,0,2,2,2]}) 
df 

Out[329]: 
    a b c 
0 1 0 0 
1 1 1 0 
2 1 2 2 
3 1 3 2 
4 1 4 2 

In [342]: 
df[df.apply(pd.Series.value_counts).dropna(thresh=2, axis=1).columns] 

Out[342]: 
    b c 
0 0 0 
1 1 0 
2 2 2 
3 3 2 
4 4 2 

輸出:

In [344]: 
df.apply(pd.Series.value_counts) 

Out[344]: 
    a b c 
0 NaN 1 2 
1 5 1 NaN 
2 NaN 1 3 
3 NaN 1 NaN 
4 NaN 1 NaN 

In [345]: 
df.apply(pd.Series.value_counts).dropna(thresh=2, axis=1) 

Out[345]: 
    b c 
0 1 2 
1 1 NaN 
2 1 3 
3 1 NaN 
4 1 NaN 
2

一個步驟:

df = df[[c for c 
     in list(df) 
     if len(df[c].unique()) > 1]] 

兩個步驟:

創建有超過1個不同的值的列名的列表。

keep = [c for c 
     in list(df) 
     if len(df[c].unique()) > 1] 

下降不在列 '保持'

df = df[keep]