Python 如何按条件删除列?

Python 如何按条件删除列?,python,pandas,Python,Pandas,假设df是一个DataFrame对象 如何删除只包含None、空字符串或仅包含空格字符串的df的所有列 下降的标准可以表示为当输入到以下测试函数时,所有值产生True的列: lambda x: (x is None) or not re.match('\S', str(x)) 下面我已经大致了解了它,但是我还不太熟悉Python中的正则表达式。这是我将采取的基本方法: 虚拟数据: In [1]: df Out[1]: a b c 0 None 1 1 b

假设
df
是一个
DataFrame
对象

如何删除只包含
None
、空字符串或仅包含空格字符串的
df
的所有列

下降的标准可以表示为当输入到以下测试函数时,所有值产生
True
的列:

lambda x: (x is None) or not re.match('\S', str(x))

下面我已经大致了解了它,但是我还不太熟悉Python中的正则表达式。这是我将采取的基本方法:

虚拟数据:

In [1]: df
Out[1]:
      a  b  c
0  None     1
1     b     2
2     c  x  3
3     d     4
4     e  z  5

In [2]: df.to_dict()
Out[2]:
{'a': {0: None, 1: 'b', 2: 'c', 3: 'd', 4: 'e'},
 'b': {0: ' ', 1: ' ', 2: 'x', 3: ' ', 4: 'z'},
 'c': {0: 1, 1: 2, 2: 3, 3: 4, 4: 5}}
对要删除的条件应用lambda测试:

In [3]: df.apply(lambda x: x.isin([None,""," "]))
Out[3]:
       a      b      c
0   True   True  False
1  False   True  False
2  False  False  False
3  False   True  False
4  False  False  False
In [5]: drop_cols = df.columns[df.apply(lambda x: x.isin([None,""," "])).any()]

In [6]: drop_cols
Out[6]: Index([a, b], dtype=object)
调用
any()

In [4]: df.apply(lambda x: x.isin([None,""," "])).any()
Out[4]:
a     True
b     True
c    False
使用上面的布尔序列索引df.columns,以获取要删除的列:

In [3]: df.apply(lambda x: x.isin([None,""," "]))
Out[3]:
       a      b      c
0   True   True  False
1  False   True  False
2  False  False  False
3  False   True  False
4  False  False  False
In [5]: drop_cols = df.columns[df.apply(lambda x: x.isin([None,""," "])).any()]

In [6]: drop_cols
Out[6]: Index([a, b], dtype=object)
使用df.drop()方法并传递axis=1选项以对列进行操作:

In [7]: df.drop(drop_cols, axis=1)
Out[7]:
   c
0  1
1  2
2  3
3  4
4  5
现在,如果有更多Pandas/RegEx经验的人能够理解这一点,我想你有一个不错的解决方案。

你可以使用它将你的函数应用到
数据帧的元素上:

In [19]: df = pd.DataFrame({'a': [None] * 4, 'b': list('abc') + [' '],
                            'c': [None] + list('bcd'), 'd': range(7, 11),
                            'e': [' '] * 4})

In [20]: df
Out[20]: 
      a  b     c   d  e
0  None  a  None   7   
1  None  b     b   8   
2  None  c     c   9   
3  None        d  10   

In [21]: to_drop = df.applymap(
                     lambda x: (x is None) or not re.match('\S', str(x))).all()

In [22]: df.drop(df.columns[to_drop], axis=1)
Out[22]: 
   b     c   d
0  a  None   7
1  b     b   8
2  c     c   9
3        d  10

当检查为真时,是否可以选择在列中循环并删除?
applymap
是让
re.match
函数为我工作的关键。仅使用
apply
时失败,实际上我认为OP的问题是
all
而不是
any
:)@好的,我想你是对的,我会更新答案。谢谢,实际上我认为OP的问题需要
all
而不是
any
:)这很有趣,因为这几乎是df.apply(all)