I am am trying to round numbers in a dataframe that has lists as values for each row. I need whole numbers to have no decimal and floats to only have two places after the decimal. There is an unknown number of values for each list (some lists have 2 values, some have 4 or 5 or more). Here is what I have:
df = pd.DataFrame({"A": [[16.0, 24.4175], [14.9687, 16.06], [22.75, 23.00]]})
def remove_exponent(num):
return num.to_integral() if num == num.to_integral() else num.normalize()
def round_string_float(x):
try:
return remove_exponent(Decimal(x).quantize(TWOPLACES))
except:
return x
df['A']=df['A'].apply(lambda x: [round_string_float(num) for num in x])
But this gives me: [Decimal('16'), Decimal('24.42')]
Here is what I am trying:
def round(num):
if str(numbers).find('/') > -1:
nom, den = numbers.split(',')
number=round_string_float(nom)
second=round_string_float(den)
return f'[{number}, {second}]'
but there has to be an easier way to do this
Here is what I want:
df = pd.DataFrame({"A": [[16, 24.42], [14.97, 16.06], [22.75, 23]]})
I would like to know have to use **args to do this but really anything that works would be good
I created an answer to this question that goes above and beyond what I wanted but I think it will help anyone looking for something similar. The problem with my company is we have to upload lists as values in a dataframe to the database. This is why the code is so ad-hoc:
from decimal import *
TWOPLACES = Decimal(10) ** -2
from natsort import natsorted
import ast
from fractions import Fraction
#----------------------------------------------------------------
# remove_exponent and round string float are designed to round whole numbers 16.00 to 16, and rounds numbers with 3 or more decimals to 2 decimals 16.254 to 16.25
def remove_exponent(num):
return num.to_integral() if num == num.to_integral() else num.normalize()
def round_string_float(x):
try:
return remove_exponent(Decimal(x).quantize(TWOPLACES))
except:
return x
#------------------------------------------------------------------------------
# frac2string converts fractions to decimals: 1 1/2 to 1.5
def frac2string(s):
i, f = s.groups(0)
f = round_string_float(Fraction(f))
return str(int(i) + round_string_float(float(f)))
#------------------------------------------
#remove duplicates is self explanitory
def remove_duplicates(A):
[A.pop(count) for count,elem in enumerate(A) if A.count(elem)!=1]
return A
# converts fractions and rounds numbers
df['matches'] = df['matches'].apply(lambda x:[re.sub(r'(?:(\d+)[-\s])?(\d+/\d+)', frac2string, x)])
# removes duplicates( this needs to be in the format ["\d","\d"]
df['matches'] = df['matches'].apply(lambda x: remove_duplicates([n.strip() for n in ast.literal_eval(x)]))