Python Pandas: String Contains and Doesn't Contain
You're almost there, you just haven't got the syntax quite right, it should be:
df[(df.str.contains("b") == True) & (df.str.contains("a") == False)]
Another approach which might be cleaner if you have a lot of conditions to apply would to be to chain your filters together with reduce or a loop:
from functools import reduce
filters = [("a", False), ("b", True)]
reduce(lambda df, f: df[df.str.contains(f[0]) == f[1]], filters, df)
#outputs b2
Either:
>>> ts.str.contains('b') & ~ts.str.contains('a')
0 False
1 False
2 True
3 False
dtype: bool
or use regex:
>>> ts.str.contains('^[^a]*b[^a]*$')
0 False
1 False
2 True
3 False
dtype: bool