选择列(如果它们的任何行包含某个字符串)

时间:2019-06-21 13:46:10

标签: python pandas dataframe

如果列中的任何值包含字符串,则我尝试获取DataFrame中列的列表。例如,在下面的数据框中,我想要一个字符串列表中包含%的列的列表。我可以使用for循环和series.str.contains方法来完成此操作,但似乎不是最佳方法,尤其是对于较大的数据集。有更有效的方法吗?

import pandas as pd

df = pd.DataFrame({'A': {0: '2019-06-01', 1: '2019-06-01', 2: '2019-06-01'},
                   'B': {0: '10', 1: '20', 2: '30'},
                   'C': {0: '10', 1: '20%', 2: '30%'},
                   'D': {0: '10%', 1: '20%', 2: '30'},
               })

DataFrame

            A   B    C    D
0  2019-06-01  10   10  10%
1  2019-06-01  20  20%  20%
2  2019-06-01  30  30%   30

当前方法

col_list = []
for col in df.columns:
    if (True in list(df[col].str.contains('%'))) is True:
        col_list.append(col)

输出

['C', 'D']

6 个答案:

答案 0 :(得分:10)

stackany

df.columns[df.stack().str.contains('%').any(level=1)]

Index(['C', 'D'], dtype='object')

理解力

[c for c in df if df[c].str.contains('%').any()]

['C', 'D']

filter

[*filter(lambda c: df[c].str.contains('%').any(), df)]

['C', 'D']

Numpy的find

from numpy.core.defchararray import find

df.columns[(find(df.to_numpy().astype(str), '%') >= 0).any(0)]

Index(['C', 'D'], dtype='object')

答案 1 :(得分:8)

首先使用DataFrame.select_dtypes仅过滤对象列,显然是字符串列。

然后使用DataFrame.applymap进行元素检查,并使用DataFrame.any返回True,如果每列至少有一个,则可能使用过滤器列:

c = df.columns[df.select_dtypes(object).applymap(lambda x: '%' in str(x)).any()].tolist()
print (c)
['C', 'D']

或者每列使用Series.str.contains,如果所有字符串列都应忽略na参数:

f = lambda x: x.str.contains('%', na=False)
c = df.columns[df.select_dtypes(object).apply(f).any()].tolist()
print (c)
['C', 'D']

答案 2 :(得分:6)

尝试一下:

df.columns[df.apply(lambda x: x.str.contains("\%")).any()]

答案 3 :(得分:6)

replace比较,并创建一个掩码以相应地为列编制索引:

df.loc[:,(df != df.replace('%', '', regex=True)).any()]
     C    D
0   10  10%
1  20%  20%
2  30%   30

df.columns[(df != df.replace('%', '', regex=True)).any()]
# Index(['C', 'D'], dtype='object')

这避免了循环applyapplymap的需要。

答案 4 :(得分:5)

让我们做melt

df.melt().loc[lambda x :x.value.str.contains('%'),'variable'].unique()
Out[556]: array(['C', 'D'], dtype=object)

答案 5 :(得分:0)

看看下面的解决方案也适用于对象数据类型。

[c for c in dfif df[c].eq("CSS").any()]