2013-11-26 82 views
14

我有一个数据帧,可能有也可能不具有相同的值的列。例如熊猫dataframe删除恒定列

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

我想只返回

row A 
    1  9  
    2  7  
    3  5  
    4  2 

有没有一种简单的方法,并确定如果有这些列的存在,然后删除它们?

回答

20

我相信这个选项会比其他的答案更快这里,如果一个非唯一值,发现它会遍历数据帧只有一次比较和短路。

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

呃:<>'。 –

+0

@AndyHayden帕斯卡尔习惯难改。我改变了它。 – chthonicdaemon

+0

+1感谢您的更改。这种短路在任何情况下都已经完成!=每个元件的比较,所以DSM的解决方案可能会更有效率......想知道更好的短路解决方案。 –

13

忽略NaN像往常一样,如果nunique() == 1的列是恒定的。所以:

>>> 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)'更简单'df.nunique()',至少在Pandas 0.20.3中。 – EOL

+0

如果我们希望NaN被认为是一个独特的值,'df.nunique(dropna = False)'效果很好(它处理NaN≠NaN这一事实,因为我们期望将所有NaN值计算为相同的值,尽管它们不相等)。 – EOL

2

假设数据帧是完全型数字的:

可以尝试:

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

这将删除常数列(即方差= 0)。

如果数据帧的类型为数字和对象,那么你应该尝试:

>>> 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) 

将下降只有数字型常量列。

如果你也想忽略/删除常量枚举列,你应该尝试:

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

大概你会想要'df = df.loc [:,〜df.var()== 0.0]'否则你要选择0列。对于可能的浮点错误,可能还需要执行'np.isclose(0,df.var())' – jeremycg

0

这里是我的解决方案,因为我需要做两件事对象和数值列。没有声称它的超级效率或任何东西,但它完成了工作。

def drop_constants(df): 
    """iterate through columns and remove columns with constant values (all same)""" 
    columns = df.columns.values 
    for col in columns: 
     # drop col if unique values is 1 
     if df[col].nunique(dropna=False) == 1: 
      del df[col] 
    return df 

额外的警告,它不会工作在列或数组的列上,因为它们不可哈希。