anagha s
anagha s

Reputation: 364

How to simplify code to check ranges in pandas

with columns as L, W, H, D. Each of them have range from 10 to 100, if it goes beyond this it is fail else it is pass

How can i simplify this code. I tried using if condition which failed

def Target(FM):

     if (df['L'] < 10 or df['L'] > 120):
        return 'L-Fail'
     else:
        return 'Pass'


     elif (df['W'] < 10 or df['W'] > 120):
        return 'W-Fail'
     else:
        return 'Pass'


     elif (df['H'] < 10 or df['H'] > 120):
        return 'H-Fail'
     else:
        return 'Pass'


     elif(df['D'] < 10 or df['D'] > 120):
        return 'D-Fail'
     else:
        return 'Pass'


     df['Remarks_Target'] = df.apply(Target, axis = 1)

      L       W       H       D     Remarks

      1       20      30      40    L-Fail
      10      40      0       50    Pass
      15      30      30      60    Pass
      60      90      80      300   D-Fail
      50      30      30      120   Pass
      10      10      120     120   Pass
      30      20      9       80    H-Fail
      14      5       85      34    W-Fail

Upvotes: 1

Views: 278

Answers (3)

Andy L.
Andy L.

Reputation: 25239

Create boolean mask df_m directly on the whole df. Next, use dot and string concat and fillna

df_m = ((df < 10) | (df > 120))
df['Remarks'] = (df_m.dot(df.columns).str[0] + '-Fail').fillna('pass')

Out[293]:
    L   W    H    D Remarks
0  1   20  30   40   L-Fail
1  10  40  0    50   H-Fail
2  15  30  30   60   pass
3  60  90  80   300  D-Fail
4  50  0   30   120  W-Fail
5  10  10  120  120  pass

Upvotes: 1

iamklaus
iamklaus

Reputation: 3770

alternative

df['Remarks'] = df.astype(int).applymap(lambda x: (x < 10 or x > 120))\
                .apply(lambda x: ''.join([df2.columns[i] + '-Fail' for i in 
                range(len(x)) if x[i]]),axis=1).replace('','Pass')

    L   W    H    D Remarks
0   1  20   30   40  L-Fail
1  10  40    0   50  H-Fail
2  15  30   30   60    Pass
3  60  90   80  300  D-Fail
4  50   0   30  120  W-Fail
5  10  10  120  120    Pass

Upvotes: 1

jezrael
jezrael

Reputation: 862406

Loop per each column and set new values by Series.between, last missing values for non matched data replace by Series.fillna:

for c in ['L','W','H','D']:
    m = df[c].between(10, 120, inclusive=True)
    df.loc[~m, 'Remarks_Target'] = f'{c}-Fail'

df['Remarks_Target'] = df['Remarks_Target'].fillna('Pass')
print (df)
    L   W    H    D Remarks Remarks_Target
0   1  20   30   40  L-Fail         L-Fail
1  10  40    0   50  H-Fail         H-Fail
2  15  30   30   60    Pass           Pass
3  60  90   80  300  D-Fail         D-Fail
4  50   0   30  120  W-Fail         W-Fail
5  10  10  120  120    Pass           Pass

Similar alternative:

df['Remarks_Target'] = 'Pass'
for c in ['L','W','H','D']:
    m = df[c].between(10, 120, inclusive=True)
    df.loc[~m, 'Remarks_Target'] = f'{c}-Fail'

Upvotes: 1

Related Questions