Skip to content Skip to sidebar Skip to footer

Round Values Of A Python Dataframe Column According To Authorized Values

I have this dataframe : df = pd.DataFrame({'id':[1,2,3,4], 'score':[0.35,3.4,5.5,8]}) df id score 0 1 0.35 1 2 3.4 2 3 5.5 3 4 8 and this list : L = list(range

Solution 1:

Numpy solution is better if large DataFrame and performance is important:

L = list(range(1,7))
a =  np.array(L)

df['score'] = a[np.argmin(np.abs(df['score'].values - a[:, None]), axis=0)]
print (df)
   id  score
0   1      1
1   2      3
2   3      5
3   4      6

How it working:

First is converted list to array:

print (a)
[1 2 3 4 5 6]

Then subtract with broadcasting with [:, None] to 2d array of all combinations:

print (df['score'].values - a[:, None])
[[-0.65  2.4   4.5   7.  ]
 [-1.65  1.4   3.5   6.  ]
 [-2.65  0.4   2.5   5.  ]
 [-3.65 -0.6   1.5   4.  ]
 [-4.65 -1.6   0.5   3.  ]
 [-5.65 -2.6  -0.5   2.  ]]

Convert values to absolute:

print (np.abs(df['score'].values - a[:, None]))
[[0.65 2.4  4.5  7.  ]
 [1.65 1.4  3.5  6.  ]
 [2.65 0.4  2.5  5.  ]
 [3.65 0.6  1.5  4.  ]
 [4.65 1.6  0.5  3.  ]
 [5.65 2.6  0.5  2.  ]]

Get positions of minimal values:

print (np.argmin(np.abs(df['score'].values - a[:, None]), axis=0))
[0 2 4 5]

So if use indexing get values of a:

print (a[np.argmin(np.abs(df['score'].values - a[:, None]), axis=0)])
[1 3 5 6]

Solution 2:

You were really close! I updated the value in the DataFrame and tidied up your lambda function.

df = pd.DataFrame({'id':[1,2,3,4], 'score':[0.35,3.4,5.5,8]})
L = list(range(1,7))

df['score'] = df['score'].apply(lambda num : min(L, key=lambda x:abs(x-num)))

Output:

>>> df
   id  score
0   1      1
1   2      3
2   3      5
3   4      6

Post a Comment for "Round Values Of A Python Dataframe Column According To Authorized Values"