based on column cell value how to extract specific no# of character from string using python

Viewed 43

Like Left formula we Used in Excel same as I want to extract no. of character from Policy no. column based on Insurer column like.....

if insurer is HDFC then Extract only 10 character form the sting and if insurer is tata then Extract only 7 character form the sting. and if insurer other than HDFC & tata then leave it as blank.

also see hdfc insure comes with lot of different name.

How I will achieve this in python

Insurer Policy no. Expected OutPut
Hdfc 4509242332 4509242332
Tata tatadigitNational tatadig
Hdfc ergo 09082323ab12sd 09082323ab
HDFC nolanheroman nolanherom
Tata 97543007356 9754300
Tata pqrsequence2o202 pqrsequ
Tata 987654321 9876543
HDFC health ergo nolanheroman nolanherom
Digit 1733choola
star naahiHonaar
3 Answers

You can use the str accessor per group with help of a dictionary:

num = {'hdfc': 10, 'tata': 7}

# identify insurer from first word (can be changed to another method)
group = df['Insurer'].str.extract('(\w+)', expand=False).str.lower()

df['Expected OutPut'] = (df.groupby(group)['Policy no.']
                           .transform(lambda g: g.str[:num[g.name]]
                                             if g.name in num else '')
                        )

output:

            Insurer         Policy no. Expected OutPut
0              Hdfc         4509242332      4509242332
1              Tata  tatadigitNational         tatadig
2         Hdfc ergo     09082323ab12sd      09082323ab
3              HDFC       nolanheroman      nolanherom
4              Tata        97543007356         9754300
5              Tata   pqrsequence2o202         pqrsequ
6              Tata          987654321         9876543
7  HDFC health ergo       nolanheroman      nolanherom
8             Digit         1733choola                
9              star        naahiHonaar                

update: enforce a minimal length

num = {'hdfc': 10, 'tata': 7}

group = df['Insurer'].str.extract('(\w+)', expand=False).str.lower()

df['Expected OutPut'] = (df.groupby(group)['Policy no.']
                           .transform(lambda g: g.mask(g.str.len()<num[g.name], '')
                                                 .str[:num[g.name]]
                                             if g.name in num else '')
                        )

output:

            Insurer         Policy no. Expected OutPut
0              Hdfc         4509242332      4509242332
1              Tata  tatadigitNational         tatadig
2         Hdfc ergo     09082323ab12sd      09082323ab
3              HDFC             nolanh                   # example here
4              Tata        97543007356         9754300
5              Tata   pqrsequence2o202         pqrsequ
6              Tata          987654321         9876543
7  HDFC health ergo       nolanheroman      nolanherom
8             Digit         1733choola                
9              star        naahiHonaar                

Another idea is to create a helper function clipper. m contains the number of characters to clip per row (assuming that the first 4 characters will be hdfc/tata/other), then the vectorized clipper function can be applied to Policy no. and m.

import numpy as np

def clipper(string, stop):
    return string[:stop]

m = df.Insurer.str[:4].str.lower().map({"hdfc": 10, "tata": 7}).fillna(0).astype(int)
df["Expected OutPut"] = np.vectorize(clipper)(df["Policy no."], m)

Check Below Answer using np.where, Expected_Output_Answer is calculated column

import pandas as pd
import numpy as np

df['Expected_Output_Answer'] = np.where(df['Insurer'].str.contains('hdfc', case=False), 
                                 df['Policy no.'].str[:10],
                                 np.where(df['Insurer'].str.contains('tata', case=False),
                                 df['Policy no.'].str[:7],
                                 ""
                                 )
                                 )
df

Output:

enter image description here

Related