I am NOT trying to round to the nearest 0.5. I know there are questions on here that address that. Rather, I am trying to change the decimal value of each value in each row to 0.5 while maintaining the same leading integer. For example, I have df
:
df = pd.DataFrame({'foo':[1.5,5.5,7.11116],'bar':[3.66666661, 10.5, 4.5],'baz':[8.5,3.111118,2.5]},index=['a','b','c'])
df
foo bar baz
a 1.50000 3.666667 8.500000
b 5.50000 10.500000 3.111118
c 7.11116 4.500000 2.500000
I would like each cell to end in 0.5. As you can see, there are some erroneous values. Here is my intended output:
foo bar baz
a 1.5 3.5 8.5
b 5.5 10.5 3.5
c 7.5 4.5 2.5
At first I thought I could maybe iterate through the columns in a list comprehension, but then figured a combination of where()
and apply()
, or maybe just apply()
with a lambda function might be more readable:
df = df.where(df % 0.5 == 0, 'fix this')
df
foo bar baz
a 1.5 fix this 8.5
b 5.5 10.5 fix this
c fix this 4.5 2.5
Where I am stumped is trying to create a function that changes the decimal value to .5 rather than rounding to the nearest 0.5 (which, for example, in this case, round 3.111118 to 3.0 when I want 3.5).
You can floor
(or convert to int with astype
), then add
0.5:
import numpy as np
out = np.floor(df).add(0.5)
Or:
out = df.astype(int).add(0.5)
Output:
foo bar baz
a 1.5 3.5 8.5
b 5.5 10.5 3.5
c 7.5 4.5 2.5
NB. a quick test suggests that floor
is about 30% faster.