Python Forum

Full Version: applying and(&) ,or(|) in conditions does not result output correctly as expected
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I have data as below(sample only, data will have all combinations of below values). I have to create new column based conditions applied on 3 columns.
Output:
A B C Normal Normal Normal High High High High High Low Low Low High Normal Normal Low Normal Normal High Normal High High No Test No Test High No Test No Test Low No Test No Test No Test No Test High High
def flag_df(df):

    if df[(df['A']=='Normal') & (df['B']=='Normal') & (df['C']=='Normal')]:
        return 'Normal'
    elif df[(df['A']=='High']) & (df['B']=='High') & (df['B']=='Low')]:
        return 'OH'
    elif df[(df['A']=='Normal']) & (df['B']=='Normal') & (df['C']=='Low')]:
        return 'SHPE'
    elif df[(df['A']=='Normal']) & (df['B']=='Normal') & (df['C']=='High')]:
        return 'SHPO'
    elif df[(df['A']=='No Test']) & (df['B']=='No Test') & (df['C']=='No Test')]:
        return 'No Test'
    elif df[(df['A']=='No Test']) | (df['B']=='No Test') & (df['C']=='High')]:
        return 'SHPO'   
df['D'] = df.apply(flag_df, axis = 1)  
The results are coming correctly for below
#expect is col-A or Col-B has "High" but Col C has "High" it should label Col-D as 'SHPO'
elif df[(df['A']=='No Test']) | (df['B']=='High') & (df['C']=='High')]:
        return 'SHPO'   
#expect is col-A AND Col-B has "no Test" but Col C has "High" it should label Col-D as 'SHPO'
elif df[(df['A']=='No Test']) & (df['B']=='No Test') | (df['C']=='High')]:
        return 'SHPO'  
How to work with | or & operators on 3 or more column conditions, is there a better approach to write a function? Appreciate your help, Thank you!!!
& and | are bitwise operators for use with integers, typically integers used as bit flags. 'and' and 'or' are logical operators intended to be used with truth values. Furthermore, and/& is evaluated before or/|, due to order of operations. If you are doing multiple tests they may not be occurring in the order you expect.
Thank you very much for quick response. I tried to use 'and' 'or' as the column has string but not sure why it did not work. It worked well with bitwise operators & |

I was getting this error when I used "and" , which I just tried again after your response, what you do think the issue here ? the dtype for these colms was 'object' and I converted to 'string' . Please suggest

Output:
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-714-eeb5bb60c70f> in <module> ----> 1 df111=df[(df['A']=='High') and (df['B']=='High') and (df['C']=='Normal')] 2 df111.head(1000) C:\BhargaviM\MyAnaconda\lib\site-packages\pandas\core\generic.py in __nonzero__(self) 1574 raise ValueError("The truth value of a {0} is ambiguous. " 1575 "Use a.empty, a.bool(), a.item(), a.any() or a.all()." -> 1576 .format(self.__class__.__name__)) 1577 1578 __bool__ = __nonzero__ ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
I am sorry I realized that cols A, B and C are still in object even when tried to convert the string df['A'].astype('str)

I can open a new one though, but I would like to check if the solution above works before i close this post. Thanks
The error is pretty clear. A Series does not have an inherent truth value like other Python objects, because it's not clear how that value would be calculated. You need to use one of the methods listed to convert to a truth value, depending how how you want it calculated.