简体   繁体   中英

Python: Inserting a row if a condition is met in pandas dataframe for multiple conditions

So I have dataframe like below:

Id     a_no    desc       flag_1    flag_2 
100     20     test         1         0
100     25     new_test     1         1
110     25     new_test     0         1

Now I am trying to add two columns msg and final_flag with the following logic

if len(desc) < 5, then msg = 'Short length' and final_flag = 'Reject'
if flag_1 == 0, then msg = 'Missing_item' and final_flag = 'Error'
if flag_2 == 0, then msg = 'Find_item' and final_flag = 'Error'

In order to achieve the above I am trying the below piece of code

df['msg'] = np.where(df['desc'].str.len() < 5,'Short length',\
            np.where(df['flag_1']==0,'Missing_item',\
            np.where(df['flag_2']==0,'Find_item','All is Good')))
df['final_flag'] = np.where(df['msg'].str.contains('Missing | Find',regex=True),'Error',np.where(df['msg'].str.contains('Good',regex=True),'Accepted','Reject'))

Using the above code, I am not getting the desired output as follows:

Id     a_no    desc       flag_1    flag_2      msg             final_flag
100     20     test         1         0     'Short length'         Reject
100     20     test         1         0     'Find Item'            Error <--as flag_2 ==0 
100     25     new_test     1         1     'All is Good'          Accepted
110     25     new_test     0         1     'Missing Item'         Error

Ie for each condition (or logic as shown above), if the condition is satisfied, a row is inserted in the final dataframe.

I can see my code snippet is not sufficient enough.

Am I missing out anything?

So I have worked out something like below:

# creating a column based on each logic#
df['msg_str'] = np.where(df['desc'].str.len() < 5, 'Short Length','')
df['msg_flag_1'] = np.where(df['flag_1']==0,'Missing Item','')
df['msg_flag_2'] = np.where(df['flag_2']==0,'Find Item','')
#Unpivoting the dataframe
df_melt = pd.melt(df,id_vars = ['msg_str','msg_flag_1','msg_flag_2'],value_name='msg')

The above technique shall yield a dataframe as below:

Id    a_no      variable      msg
100    20       msg_str      Short Length
100    20       msg_flag_1   
100    20       msg_flag_2   Find Item
100    25       msg_str      
100    25       msg_flag_1   
100    25       msg_flag_2  
110    25       msg_str     
110    25       msg_str_1    Missing Item
110    25       msg_str_2      

Now I add another col:

df_melt['status'] = np.where(df_melt['msg'].str.contains('Missing|Short|Find',regex=True),'Reject','Accept')

This actually solved the problem. Of course I can pivot the above df again to get the desired output.

You can use apply function as well:

dt['msg'] =''
dt['final_flag']=''
def replace_dt(x):
    if len(x['desc'])<5: 
        x.loc['msg','final_flag']=['Short length','Reject']
    if x['flag_1']==0:
        x.loc['msg','final_flag']=['Missing_item','Error']
    if x['flag_2']==0:
       x.loc['msg','final_flag']=['Find_item','Error']
    return x
dt.apply(replace_dt,axis = 1 )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM