Add a new column with condition if a string 'contains' substring?

Question:

I want to add a new column ‘check’ with the following condition:

  • ‘Suppression total’ and ‘Sup-SDM’.

OR

  • Suppression partiel and Franc SUP – Geisi

Dataframe:

Type Info
Sup_EF – SUP – SDM 2021-12-08 16:47:51.0-Suppression totale
Modif_EF – SUP – SDM 2021-12-08 16:47:51.0-Creation
Sup_EF – SUP – Geisi 2021-12-08 16:47:51.0-Suppression totale
Modif_EF – Franc SUP – Geisi 2021-12-17 10:50:40.0-Suppression partiel

Desired output:

Type Info Check
Sup_EF – SUP – SDM 2021-12-08 16:47:51.0-Suppression total Correct
Modif_EF – SUP – SDM 2021-12-08 16:47:51.0-Creation Fail
Sup_EF – SUP – Geisi 2021-12-08 16:47:51.0-Suppression total Fail
Modif_EF – Franc SUP – Geisi 2021-12-17 10:50:40.0-Suppression partiel Correct

Code:

if ('SUP - SDM' in df["Type"].values) and ('Suppression total' in df['Info'].values):
    df['Check'] = "Correct"
elif ('Franc SUP - Geisi' in df["Type"].values) and ('Suppression partiel' in df['Info'].values):
    df['Check'] = "Correct"
else:
    df['Check'] = "Fail"

But my output looks like this:

Type Info Check
Sup_EF – SUP – SDM 2021-12-08 16:47:51.0-Suppression total Fail
Modif_EF – SUP – SDM 2021-12-08 16:47:51.0-Creation Fail
Sup_EF – SUP – Geisi 2021-12-08 16:47:51.0-Suppression total Fail
Modif_EF – Franc SUP – Geisi 2021-12-17 10:50:40.0-Suppression partiel Fail

Or when i used this code, it shows Keyerror: ‘Info’

df['Check'] = df.apply(lambda x: 'Correct' if ('Suppression total' in x['Info'] and 'Sup-SDM' in x['Type']) or ('Suppression partiel' in x['Info'] and 'Franc SUP - Geisi' in x['Type']) else 'Fail')
Asked By: Cherry cherry

||

Answers:

You need add axis=1 to apply on rows and fix Sup-SDM to SUP - SDM

df['Check'] = df.apply(lambda x: 'Correct' if ('Suppression total' in x['Info'] and 'SUP - SDM' in x['Type']) or ('Suppression partiel' in x['Info'] and 'Franc SUP - Geisi' in x['Type']) else 'Fail', axis=1)

Better is to np.where,

m1 = ( df['Info'].str.contains('Suppression total')  & df['Type'].str.contains('SUP - SDM'))
df['Check'] = np.where(m1 | m2, 'Correct', 'Fail')
Answered By: Ynjxsjmh

You can row-wise apply a function to the dataframe that checks whether or not the strings are in the columns.

df = pd.DataFrame({'Type': {0: 'Sup_EF - SUP - SDM',
  1: 'Modif_EF - SUP - SDM',
  2: 'Sup_EF - SUP - Geisi',
  3: 'Modif_EF - Franc SUP - Geisi'},
 'Info': {0: '2021-12-08 16:47:51.0-Suppression totale',
  1: '2021-12-08 16:47:51.0-Creation',
  2: '2021-12-08 16:47:51.0-Suppression totale',
  3: '2021-12-17 10:50:40.0-Suppression partiel'},
 'Check': {0: 'good', 1: 'not good', 2: 'not good', 3: 'good'}})

def f(s):
    if ("SUP - SDM" in s['Type'] and "Suppression total" in s['Info']) or ("Franc SUP - Geisi" in s['Type'] and "Suppression partiel" in s['Info']):
        return "Correct"
    else:
        return "Fail"
    
df['Check'] = df.apply(f, axis=1)
Answered By: Sandertjuhh

You might want to use numpy as it can be extended to have more than two conditions and result if needed easily:

df['check'] = np.where((df.Type.str.contains('SUP - SDM') & df.Info.str.contains('Suppression total')
                       | (df.Type.str.contains('Franc SUP - Geisi') & (df.Info.str.contains('Suppression partiel')))),'correct','fail')
Answered By: masoud
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.