简体   繁体   中英

Check if string in pandas database contains substring and remove

I am cleaning a column of a pandas data frame 'PERCENTAGE_AFFECTED'. It has contains integer ranges (eg: "70-80", "70 and 80", "65 to 70").

I am trying to create a function to clean all these up to create integer averages.

THIS WORKS>>>

def clean_split_range(row):
# Initial value contains the current value for the PERCENTAGE AFFECTED column
initial_perc = str(row['PERCENTAGE_AFFECTED'])
chars = '<>!,?":;() '

#Remove chars in initial value
if any(c in chars for c in initial_perc): 
    split_range =[]
    cleanWord = ""
    for char in initial_perc:            
        if char in chars:
            char = ""
        cleanWord += char
    split_range.append(cleanWord)
    initial_perc = ''.join(split_range)



#Split initial_perc into two elements if "-" is found   
split_range = initial_perc.split('-')
# If a "-"  is found, split_date will contain a list with two items
if len(split_range) > 1:        
    try:
        final_perc = int(reduce(lambda x, y: x + y, list(map(int, split_range))) / (len(split_range)))
    except ValueError:
        split_range = split_range[0].split('+')
        final_perc = split_range[0]            
    finally:
        if str(final_perc).isalpha():
            final_perc = 0

elif initial_perc.find('and') != -1:
    split_other = initial_perc.split('and')
    if len(split_other) > 1:
        try:
            final_perc = int(reduce(lambda x, y: x + y, list(map(int, split_other))) / (len(split_other)))
        except ValueError:
            split_other = split_other[0].split('+')
            final_perc = split_other[0]
        finally:
            if str(final_perc).isalpha():
                final_perc = 0

elif initial_perc.find('to') != -1:
    split_other = initial_perc.split('to')
    if len(split_other) > 1:
        try:
            final_perc = int(reduce(lambda x, y: x + y, list(map(int, split_other))) / (len(split_other)))
        except ValueError:
            split_other = split_other[0].split('+')
            final_perc = split_other[0]
        finally:
            if str(final_perc).isalpha():
                final_perc = 0   



elif initial_perc.find('±') != -1:
    split_other = initial_perc.split('±')
    final_perc = split_other[0]

elif initial_perc.startswith('over'):
    split_other = initial_perc.split('over')
    final_perc = split_other[1]     

elif initial_perc.find('around') != -1:
    split_other = initial_perc.split('around')
    final_perc = split_other[1]



elif initial_perc.isalpha():
    final_perc = 0

# If no "-" is found, split_date will just contain 1 item, the initial_date
else:
    final_perc = initial_perc

return final_perc

BUT: I am trying to simplify this so that if the entry contains the "-", "and", "to" substring. I have created a list of substrings (split_list) that I want to split by and remove:

def new_clean_split_range(row):
# Initial value contains the current value for the PERCENTAGE AFFECTED column
initial_perc = str(row['PERCENTAGE_AFFECTED'])
chars = '<>!,?":;() '
split_list = ['-','and']



# Split initial_perc into two elements if "-" is found    
if any(a in initial_perc for a in split_list):
    for a in split_list:
        split_range = initial_perc.split(a)
        # If a "-"  is found in split_list, initial_perc will contain a list with two items
        if len(split_range) > 1:        
            try:
                final_perc = int(reduce(lambda x, y: x + y, list(map(int, split_range))) / (len(split_range)))
            except ValueError:
                split_range = split_range[0].split('+')
                final_perc = split_range[0]            
            finally:
                if str(final_perc).isalpha():
                    final_perc = 0
        else:
            final_perc = initial_perc  



#Remove chars in initial value
if any(c in chars for c in initial_perc): 
    split_range =[]
    cleanWord = ""
    for char in initial_perc:            
        if char in chars:
            char = ""
        cleanWord += char
    split_range.append(cleanWord)
    initial_perc = ''.join(split_range)
    split_range = ''    



elif initial_perc.find('±') != -1:
    split_other = initial_perc.split('±')
    final_perc = split_other[0]

elif initial_perc.startswith('over'): 
    split_other = initial_perc.split('over')
    final_perc = split_other[1]     

elif initial_perc.find('around') != -1:
    split_other = initial_perc.split('around')
    final_perc = split_other[1]









elif initial_perc.isalpha():
    final_perc = 0

# If no "-" is found, split_date will just contain 1 item, the initial_date
else:
    final_perc = initial_perc

return final_perc

Any help would be great :)

I would suggest to use the regex.

check this out.

import re
results = re.findall(r"(\d{2,3}\.?\d*).*?(\d{2,3}\.?\d*)", x).pop() #x is input
print results
#results will be tuple and you can handle it easily.

checked with follwoing input and outputs,

Input
'70.5894-80.9894'
'70 and 85',
'65 to 70',
'72 <>75'

output
('70.5894', '80.9894')
('70', '85')
('65', '70')
('72', '75')

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