如果列中的任何值包含字符串,则我尝试获取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'},
})
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']
答案 0 :(得分:10)
stack
与any
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']
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')
这避免了循环apply
或applymap
的需要。
答案 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()]