0

I have a dataframe df_matching that I want to get when 2 columns is not matching at certain values using xor operator so

While this code works:

df_matching.query('(group == "treatment" and landing_page != "new_page") or  (group != "treatment" and landing_page == "new_page")')

This code doesn't:

df_matching.query('(group == "treatment") ^ (landing_page == "new_page")')

Although all the searches leads that XOR operator in python is "^" and I know that XOR in SQL is XOR but neither works. What is the best way to put XOR in df.query()?

Barmar
  • 741,623
  • 53
  • 500
  • 612
KZD
  • 23
  • 7
  • 2
    How about `(group == "treatment") != (landing_page == "new_page")`? – Barmar Sep 04 '21 at 05:06
  • @Barmar as a concept it is not correct look at the following answer in this https://stackoverflow.com/questions/432842/how-do-you-get-the-logical-xor-of-two-variables-in-python "There is problem with using "!=" as xor. You would probably expect bool(a) != bool(b) != bool(c) to be the same as bool(a) ^ bool(b) ^ bool(c). So do casts to bool, but I would recommend ^. To know what's going up in the first example look up "operator chaining" – KZD Sep 04 '21 at 07:41
  • That's why I didn't post it as an answer. – Barmar Sep 04 '21 at 07:42
  • @Barmat then it is accepted as a workaround :) – KZD Sep 04 '21 at 07:46

2 Answers2

1

Don't know when they introduced the ^ bitwise XOR but in my current pandas 1.3.5 it's working, although not in query() statements. The solution would be:

# create boolean masks A and B
A = df_matching.group == 'treatment'
B = df_matching.landing_page == 'new_page'
df_matching[A ^ B]
0

The python bitwise XOR (^) isn't valid in a pandas query, as you noted. It doesn't look like there's a packaged pd.query() XOR function.

To compensate, I'd use the basic definition of a 2-element XOR, i.e, ( A | B ) & ~( A & B ), and set conditions as variables.

a = 'group == "treatment"'
b = 'landing_page == "new_page"'

xor_ab = '('+a+'|'+b+') & ~('+a+'&'+b+')'

df_matching.query(xor_ab)

(Slightly more compact.)

garlic_rat
  • 99
  • 6
  • it is more neat and readable but I'm looking for xor operator. or a documented answer that it doesn't have which would be very strange! – KZD Sep 04 '21 at 07:49