Append % symbol to dict numeric values in a dataframe column

Viewed 38

I have a dataframe like as shown below

key, values_list
 1, {'ABC':100}
 2, {'DEF':100}
 3, {'ASE':95,'ABC':5}
 4, {'ABC':55,'ASE':40,'DEF':5}
 5, {'DEF':90,'ABC':5,'ASE':2.5,'XYZ':2.5} 

I would like to do the below

a) Convert dict values to string and include % symbol at the end of each string

So, I tried the below

df['values_list'].str.replace(r'[0-9]+', '[0-9]%') # Approach 1
np.where(df['values_list'].str.isdigit(),df['values_list']+'%',df['values_list']) #Approach 2

I expect my output to be like as below. You can see that we have % symbol for each numeric value.

key, values_list
 1, {'ABC':100%}
 2, {'DEF':100%}
 3, {'ASE':95%,'ABC':5%}
 4, {'ABC':55%,'ASE':40%,'DEF':5%}
 5, {'DEF':90%,'ABC':5%,'ASE':2.5%,'XYZ':2.5%} 
1 Answers

For this purpose, you can use apply and then add % to each value of dict like below:

>>> df['values_list'] = df['values_list'].apply(lambda x: {k: f'{v}%' for k,v in x.items()})
# OR
>>> df['values_list'] = df['values_list'].astype('str').str.replace('([+-]?[0-9]+\.?[0-9]*)', r'\1%', regex=True)
>>> df
   key                                        values_list
0    1                                    {'ABC': '100%'}
1    2                                    {'DEF': '100%'}
2    3                        {'ASE': '95%', 'ABC': '5%'}
3    4          {'ABC': '55%', 'ASE': '40%', 'DEF': '5%'}
4    5  {'DEF': '90%', 'ABC': '5%', 'ASE': '2.5%', 'XY...

Benchmark on colab:

import pandas as pd
import numpy as np

newdf = pd.DataFrame(np.repeat(df.values, 100_000, axis=0), columns = ['key', 'values_list'])
print(len(newdf)) #repeat each row 100_000 -> 5*100_000
# 500_000

%timeit newdf['values_list'].apply(lambda x: {k: f'{v}%' for k,v in x.items()})
# 1 loop, best of 5: 651 ms per loop

%timeit newdf['values_list'].astype('str').str.replace('([+-]?[0-9]+\.?[0-9]?)', r'\1%', regex=True) # Approach 1
# 1 loop, best of 5: 3.3 s per loop
Related