1

I am trying to replace fractions in a string that come in different formats. Some of the formats look like 1/2 , 1 1/2, 1-1/2.

Input='This is the first fraction 1/2'
Input_two='This is the second fraction 3-1/8'
Input_three='This is the third fraction 20 1/4'

Output='This is the first fraction 0.5'
Output_two='This is the first fraction 3.12'
Output_three='This is the first fraction 20.25'

What I have tried:

df['col]=df['col'].apply(lambda x: re.sub('\d\d?\d?.?\d+/\d+','1.5',str(x))
But this only works if you put the value in each time and a thousand different fractions

I have also tried from fractions import Fraction and from __future__ import division but cannot get these to work on strings.

1
  • 1
    If the input text is dataframe, then add the sample dataframe to the question, and you can also add pandas tag. Commented Aug 3, 2021 at 17:26

2 Answers 2

3

You can use the fractions package together with a re.sub to do this.

import re
from fractions import Fraction

Inputs=[
    'This is the first fraction 1/2',
    'This is the second fraction 3-1/8',
    'This is the third fraction 20 1/4',
    'This is the first fraction 1/2 second fraction 3-1/8 third: 10 3/4'
]

def frac2string(s):
    i, f = s.groups(0)
    f = Fraction(f)
    return str(int(i) + float(f))

[re.sub(r'(?:(\d+)[-\s])?(\d+/\d+)', frac2string, s) for s in Inputs] 

which gives you:

['This is the first fraction 0.5',
 'This is the second fraction 3.125',
 'This is the third fraction 20.25',
 'This is the first fraction 0.5 second fraction 3.125 third: 10.75']
Sign up to request clarification or add additional context in comments.

1 Comment

This works perfectly. I did replace the "s" with measure in an applied lambda function and I removed the for s in Inputs since it was an applied Lambda function but it works well! Thank you df['col']=df['col'].apply(lambda measure: [re.sub(r'(?:(\d+)[-\s])?(\d+/\d+)', frac2string, measure) )
0

Here is one solution using Series.str.replace with capturing group, then using lambda to convert the fractional values to floating points then do the replacement.

df['col'].str.replace('(\s(?:\d+)?.?\d+\/\d+)', lambda x: ' '+str(eval(x.group(0).replace(' ','+').replace('-',  '+'))), regex=True)

0       This is the first fraction 0.5
1    This is the second fraction 3.125
2     This is the third fraction 20.25
Name: col, dtype: object

PS: Since, it uses eval to convert the string fractional values to the floating values, it will throw syntaxError if the fraction part you have mentioned in the question is syntactically wrong, i.e. the actual data is different than what you have shown in the question.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.