【发布时间】:2013-01-28 03:17:07
【问题描述】:
假设df 是一个熊猫DataFrame 对象。
如何删除
df中仅包含None、空字符串或仅包含空格的字符串的所有列?
丢弃的标准可以表示为当输入以下测试函数时所有值都产生True的列:
lambda x: (x is None) or not re.match('\S', str(x))
【问题讨论】:
-
当检查为真时是否可以循环遍历列并删除?
假设df 是一个熊猫DataFrame 对象。
如何删除
df中仅包含None、空字符串或仅包含空格的字符串的所有列?
丢弃的标准可以表示为当输入以下测试函数时所有值都产生True的列:
lambda x: (x is None) or not re.match('\S', str(x))
【问题讨论】:
我基本上已经在下面弄清楚了,但我对 Python 中的 RegEx 还不太熟悉。这是我将采取的基本方法:
虚拟数据:
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
调用 any() 方法,在任何 df 列中测试 True
In [4]: df.apply(lambda x: x.isin([None,""," "])).any()
Out[4]:
a True
b True
c False
使用上面的布尔系列索引 df.columns 以获取要删除的列:
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 经验的人可以解决这个问题,我会说你有一个不错的解决方案。
【讨论】:
all 而不是 any。 :) 这很有趣,因为这几乎是df.apply(all)...It's definitely worth learning regular expressions。
您可以使用applymap 将您的函数应用于DataFrame 的元素:
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 时失败
all 而不是 any。 :)