我有一个包含五行的数据框,如下所示:
index col1 col2 col3 col4 col5
1 word1 None word1 None None
2 None word1 word2 None None
3 None None None word2 word2
4 word1 word2 None None None
我正在尝试在 any 列组合中查找包含两个字符串的所有行-在这种情况下,是第2和4行。通常,我会使用str.contains
方法按字符串过滤:
df[df['col1'].str.contains('word1 | word2'), case=False)
但是,这仅给我A)一列的结果,B)如果该列有一个单词,则为True。我凭直觉尝试过df[df[['col1', 'col2', 'col3', 'col4', 'col5']].str.contains('word1' & 'word2'), case=False)
,但是.str.contains
在DataFrame对象上不起作用。
有没有一种方法可以不使用for循环?
答案 0 :(得分:4)
使用any
s1=df.apply(lambda x : x.str.contains(r'word1')).any(1)
s2=df.apply(lambda x : x.str.contains(r'word2')).any(1)
df[s1&s2]
Out[452]:
col1 col2 col3 col4 col5
index
2 None word1 word2 None None
4 word1 word2 None None None
答案 1 :(得分:4)
如果仅查找2个单词,则可以使用np.isin
和any
来检查基础numpy
数组中的每一行是否同时包含两个元素,请使用单独的每个单词isin
:
df[np.isin(df.values, 'word1').any(1) & np.isin(df.values, 'word2').any(1)]
index col1 col2 col3 col4 col5
1 2 None word1 word2 None None
3 4 word1 word2 None None None
或者,遵循相同的逻辑,但从@coldspeed的答案中借鉴了一点:
words = ['word1','word2']
df[np.logical_and.reduce([np.isin(df.values, w).any(1) for w in words])]
index col1 col2 col3 col4 col5
1 2 None word1 word2 None None
3 4 word1 word2 None None None
答案 2 :(得分:2)
假设只需要同时包含word1和word2的行,则需要stack
,groupby
索引并在apply
内进行搜索。
words = ['word1', 'word2']
df[df.stack().groupby(level=0).apply(
lambda x: all(x.str.contains(w, case=False).any() for w in words))]
print(df)
col1 col2 col3 col4 col5
index
2 None word1 word2 None None # word1=>col2, word2=>col3
4 word1 word2 None None None # word1=>col1, word2=>col2
另一种替代方法是使用np.logical_and.reduce
:
v = df.stack()
m = pd.Series(
np.logical_and.reduce([
v.str.contains(w, case=False).groupby(level=0).transform('any')
for w in words]),
index=v.index)
df = df[m.unstack().all(1)]
print(df)
col1 col2 col3 col4 col5
index
2 None word1 word2 None None
4 word1 word2 None None None