Michael K
Michael K

Reputation: 2288

pandas indexing using multiple isin clauses

If I want to do is-in testing on multiple columns at once, I can do:

>>> from pandas import DataFrame
>>> df = DataFrame({'A': [1, 2, 3], 'B': [1, 4, 7], 'C' : [10, 12, 18]})   
>>> mask = df[['A','B']].isin({'A': [1, 3], 'B': [4, 7, 12]}).all(axis=1)
>>> df = df[mask]

That works--is there a more succinct solution?

Upvotes: 5

Views: 27648

Answers (3)

DSM
DSM

Reputation: 353099

TBH, your current approach looks fine to me; I can't see a way with isin or filter to improve it, because I can't see how to get isin to use only the columns in the dictionary or filter to behave as an all.

I don't like hardcoding column names, though, so I'd probably write this as

>>> keep = {'A': [1, 3], 'B': [4, 7, 12]}
>>> df[df[list(keep)].isin(keep).all(axis=1)]
   A  B   C
2  3  7  18

or with .loc if I needed a handle.

Upvotes: 11

Zero
Zero

Reputation: 76927

You could put both the isin conditions in &

df[df['A'].isin([1, 3]) & df['B'].isin([4, 7, 12])]
   A  B   C
2  3  7  18

You could also use query function like

c_a = [1, 3]
c_b = [4, 7, 12]
df.query('(B in @c_b) & (A in @c_a)')

   A  B   C
2  3  7  18

Upvotes: 21

EdChum
EdChum

Reputation: 394051

You could put both conditions in as a mask and use &:

In [12]:

df[(df['A'].isin([1,3])) & (df['B'].isin([4,7,12]))]
Out[12]:
   A  B   C
2  3  7  18

Here the conditions require parentheses () around them due to operator precedence

Slightly more readable is to use query:

In [15]:

df.query('A in [1,3] and B in [4,7,12]')
Out[15]:
   A  B   C
2  3  7  18

Upvotes: 6

Related Questions