Round floats in a dataframe to nearest specific float values (rounding to a non integer list)

Viewed 171

I have a dataframe like:

dict_ = {'Col1':[0.54523, 0.24223, 0.94234],'Col2':[0.992324, 0.274336, 0.245435]}
df = pd.DataFrame(dict_, columns=dict_.keys())
Col1 Col2
0.54523 0.992324
0.24223 0.274336
0.94234 0.245435

And I want only to have the specific values 0.25, 0.5, 1.0, rounding the original df dataframe to the nearest possible number on the specific values.

So, I want df to become:

Col1 Col2
0.5 1.0
0.25 0.25
1.0 0.25

How to do this in python (preferably in a pandas dataframe)?

2 Answers

Let's use numpy broadcasting to calculate the absolute differences between each value in Col1 and Col2 with the values from array [0.25, 0.5, 1.0] then use .argmin to find the index of closest values:

c = ['Col1', 'Col2']

a = np.array([0.25, 0.5, 1.0])
idx = np.abs(df[c].values[:, :, None] - a).argmin(axis=-1)
df[c] = a[idx]

Result:

   Col1  Col2
0  0.50  1.00
1  0.25  0.25
2  1.00  0.25

method1:

if the value is fix as [0.25, 0.5, 1.0], then use:

np.round(df/0.125, 0) * 0.125

method2:

  1. use pd.cut as bins add the mean values of every element in the list [0, 0.25, 0.5, 1.0], so the bins is [0, 0.125, 0.25, 0.375, 0.5, 0.75, 1.0].
  2. and the lable set as [0, 0.25, 0.25, 0.5, 0.5, 1.0]
bins = [0, 0.25, 0.5, 1.0]
labels = sorted(bins + bins)[1:-1]
print(labels) # [0, 0.25, 0.25, 0.5, 0.5, 1.0]

obj = pd.Series(bins)
bins += ((obj + obj.shift(1))/2) .dropna().tolist()
bins.sort()
print(bins) # [0, 0.125, 0.25, 0.375, 0.5, 0.75, 1.0]

dfn = pd.DataFrame()
for col in df.columns:
    dfn[col] = pd.cut(df[col], bins=bins, 
                      labels=labels, 
                      ordered=False)

print(dfn)

       Col1  Col2
    0  0.50  1.00
    1  0.25  0.25
    2  1.00  0.25
Related