1

I’m wondering why the below conditional selection isn’t working. I would expect indices 0 and 3 to be selected but this is returning nothing. Wondering if I’m missing something obvious.

In [5]: a = {'A':['this', 'is', 'an', 'example'], 'B':[None, None, None, None], 
   ...: 'C':['some', 'more', 'example', 'data']}

In [6]: df = pd.DataFrame(a)

In [7]: df
Out[7]: 
         A     B        C
0     this  None     some
1       is  None     more
2       an  None  example
3  example  None     data

This returns 2 rows:

In [8]: df.loc[(df['A'].str.len() > 3)]
Out[8]: 
         A     B     C
0     this  None  some
3  example  None  data

And this returns all rows:

In [9]: df.loc[(df['B'].isnull())]
Out[9]: 
         A     B        C
0     this  None     some
1       is  None     more
2       an  None  example
3  example  None     data

So I would expect this to return indices 0 and 3 but it doesn't return any rows

In [10]: df.loc[(df['B'].isnull() & df['A'].str.len() > 3)]
Out[10]: 
Empty DataFrame
Columns: [A, B, C]
Index: []

Any help would be appreciated.

Thanks!

2
  • 1
    Using the Series/DataFrame logical comparison operators can help cut down on all of the parentheses: df.loc[df['B'].isnull() & df['A'].str.len().gt(3)] Commented Apr 8, 2019 at 2:15
  • Yeah in Pandas it always wise to put paranthesis around each condition. (cond1) & (cond2). Commented Apr 8, 2019 at 2:18

2 Answers 2

1

You need to use separate brackets:

df.loc[(df['B'].isnull()) & (df['A'].str.len() > 3)]

         A     B     C
0     this  None  some
3  example  None  data

This is due to the Operator precedence. In your code, df['B'].isnull() & df['A'].str.len() gets evaluated first, yielding:

0    False
1    False
2    False
3     True
dtype: bool

Then the remaining comparison >3 is applied, yielding:

0    False
1    False
2    False
3    False
dtype: bool

And thus the original line returns no rows, instead of desired indices.

Sign up to request clarification or add additional context in comments.

Comments

0

It's a typo, the parenthesis have to be around the conditions, so use:

df.loc[(df['B'].isnull()) & (df['A'].str.len() > 3)]

Output:

         A     B     C
0     this  None  some
3  example  None  data

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.