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.