2015-10-15 39 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] 
相关问题