'Conditional columns from multiple string values in multiple column

I would like to make a conditional column based on the string values in 3 other columns in arcmap (field calculator). Lets say

  1. Column_1 = a, b, c, d

  2. Column_2 = x, y, z, j, 1, 2

  3. Column_3 = m, n, 0, 1,

then the return I expect in the new column is as follows:

'I' if [Column_1 is 'a' or 'b'] and [Column_2 is 'j' or '1' or '2'] and [Column_3 is 'm' or 'n'] 

'II' if [Column_1 is 'a' or 'b'] and [Column_2 is 'y' or 'z' or 'j'] and [Column_3 is '0' or '1']

Each other combination would return 'III'.

My code is :

def fnX('Column_1', 'Column_2', 'Column_3'):

  if (Column_1 == 'a' or 'b') and (Column_2 == 'j' or '1' or '2') and (Column_3 == 'm' or 'n'):
    return 'I'

  elif (Column_1 == 'a' or 'b') and (Column_2 == 'y' or 'z' or 'j') and (Column_3 == '0' or '1'):
    return 'II'

  else:
    return 'III'

I tried the code above but it didn't succeed. All returns are 'I'. Is there any other mechanic that can be used to replace if-elif-else?



Solution 1:[1]

  • When you want to compare all values of list with a scalar value, you cannot compare the entire list to the scalar directly Column_1 == 'a', you should have a loop to iterate throught each element of the list or convert a list to a numpy array np.array(Column_1 ).

  • When you have multiple conditions in your comparison you should repeat the same comparison with the other conditions: Column_1[0] == 'a' or Column_1[0] == 'b' instead of Column_1[0] == 'a' or 'b'.

  • You cannot iterate through the three lists together at the same time because Column_2 has 5 elements while other lists have only 4 elements.

I will assume that Column_2 has only the first 4 values:

Column_1 = ['a','a','a','a']
Column_2 = ['x','y','z','1']
Column_3 = ['m','n','0','1']

for i,j,k in zip(Column_1,Column_2,Column_3):
    if i in {'a','b'} and j in {'j','1','2'} and k in {'m','n'}:
        print('I')
    elif i in {'a','b'} and j in {'y','z','j'} and k in {'0','1'}:
        print('II')
    else:
        print('III')

#OUTPUT
III
III
II
III

Solution 2:[2]

I quickly rewrote your code into this based on the comments. Give it a try.

def fnX(Column_1, Column_2, Column_3):

  if (Column_1 in {'a','b'} and (Column_2 in {'j', '1','2'} and (Column_3 == {'m', 'n'}): 
    return 'I'

  elif (Column_1 in {'a', 'b'} and (Column_2 in {'y', 'z', 'j'}) and (Column_3 in {'0', '1'}): 
    return 'II'

  else: 
    return 'III'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Thu Ya Kyaw