df.loc more than 2 conditions

Viewed 49820

I have a pandas dataframe like this:

df = pd.DataFrame({"A": [1, 2, 3, 4, 5, 6], "B": [100, 200, 300, 400, 500, 
600]})

And I want to create a new column with some value if certain conditions are met. The problem is: These are multiple conditions with & and |. I know I can do this with only two conditions and then multiple df.loc calls, but since my actual dataset is quite huge with many different values the variables can take, I'd like to know if it is possible to do this in one df.loc call. I also tried np.where before, but found df.loc generally easier so it would be nice if I can stick with it.

The code I tried is

df.loc[(df.A == 1) | (df.A == 2) & (df.B == 600) | (df.B == 200), "C"] = 
"1or2and600or200"

which gives me

print(df)  
   A    B                C
0  1  100  1or2and600or200
1  2  200  1or2and600or200
2  3  300              NaN
3  4  400              NaN
4  5  500              NaN
5  6  600              NaN

This however is not what I want, as df.loc likely only considers the first two conditions. So, I would want, in this code example, the value 1or2and600or200 to be only in the first line, not in the second one. Is this possible?

Much thanks.

2 Answers

All good, except you need to take care of extra parenthesis.

df.loc[((df.A == 1) | (df.A == 2)) & ((df.B == 600) | (df.B == 200)), "C"] = "1or2and600or200"

You can also proceed with .isin for more clear and concise picture as referred by @AndrewF

df.loc[df.A.isin([1, 2]) & df.B.isin([600, 200]), 'C'] = "1or2and600or200"

Also, for your given condition, it will be present in second row, because it's where you have 200 in B

You cannot have it in the first line as the value for B in the first line is 100 and not 200. As per your requirement, the code could be in the following way:

df.loc[(df['A'].isin([1,2])) & (df['B'].isin([100])),'C'] = "1or2and600or200"

isin() is quite useful in case of multiple conditions.

Related