-1

How can I transform all float values in a dict ending in .0 to an int? Is there an elegant solution for this?

 {
   '4061_dummy': {
     'mae': 278.86288346930246,
     'best_par': {
       'metric': 'minkowski',
       'weights': 'distance',
       'n_neighbors': 6.0
     }
   },
   '4181_fourier': {
     'mae': 604.05,
     'best_par': {
       'metric': 'l1', 
       'weights': 'distance', 
       'n_neighbors': 1.0
     }
   },
   '4905_fourier': {
     'mae': 610.8769965277778,
     'best_par': {
       'metric': 'minkowski',
       'weights': 'uniform',
       'n_neighbors': 24.0
     }
   },
   'time': 1.47
 }

My solution for this problem you can see in the following.

for i in a:
    if isinstance(a[i], dict):
        for key in a[i]["best_par"]:
            if isinstance(a[i]["best_par"][key], float):
                if int(a[i]["best_par"][key]) == a[i]["best_par"][key] and isinstance(a[i]["best_par"][key], float):
                    a[i]["best_par"][key] = int(a[i]["best_par"][key])
                    print(a[i]["best_par"][key])
Julio Reckin
  • 146
  • 1
  • 10
  • Iterate over your dictionary, check if `x == int(x)` and if so, replace `x` with `int(x)`? – Chris Jan 26 '22 at 18:48
  • There seem to be three different steps needed: 1) walk the dict and find float values; 2) [check if the float is a whole number](/q/21583758/4518341); 3) convert it to int. Which part(s) do you need help with? Please [edit] to clarify. For more tips, see [ask]. – wjandrea Jan 26 '22 at 18:52
  • 2
    `ctrl+h` replace all `".0"` with `""` in the file – 12944qwerty Jan 26 '22 at 18:53
  • @12944qwerty Brilliant solution! I'll transform the dict to str and then I can replace it like you said – Julio Reckin Jan 26 '22 at 18:56
  • @Chris the comparison would not work in all cases. Perhaps, it's safer to change the data to string and check the pattern `[0-9]+.0`. – Amin Jan 26 '22 at 19:18
  • 2
    Replacing all `".0"` with `""` would turn `604.05` into `6045`, would it not? – Chris Jan 26 '22 at 19:19

3 Answers3

3

Recursive solution:

def convert_integer_floats_to_ints(d):
    for key, val in d.items():
        if isinstance(val, float) and val == int(val):                
            d[key] = int(val)
        elif isinstance(val, dict):
            convert_integer_floats_to_ints(val)
MikeM
  • 13,156
  • 2
  • 34
  • 47
1

the only solution i can think of:

for i in data.keys():
    if i!='time': data[i]['best_par']['n_neighbors'] = int(data[i]['best_par']['n_neighbors'])

Output:

{'4061_dummy': {'best_par': {'metric': 'minkowski',
   'n_neighbors': 6,
   'weights': 'distance'},
  'mae': 278.86288346930246},
 '4144_dummy': {'best_par': {'metric': 'l1',
   'n_neighbors': 4,
   'weights': 'uniform'},
  'mae': 116.66041666666666},
 '4181_fourier': {'best_par': {'metric': 'l1',
   'n_neighbors': 1,
   'weights': 'distance'},
  'mae': 604.05},
 '4331_fourier': {'best_par': {'metric': 'minkowski',
   'n_neighbors': 1,
   'weights': 'distance'},
  'mae': 305.13958333333335},
 '4555_fourier': {'best_par': {'metric': 'minkowski',
   'n_neighbors': 1,
   'weights': 'distance'},
  'mae': 888.1520833333333},
 '4583_fourier': {'best_par': {'metric': 'l1',
   'n_neighbors': 1,
   'weights': 'distance'},
  'mae': 601.28125},
 '4853_dummy': {'best_par': {'metric': 'minkowski',
   'n_neighbors': 2,
   'weights': 'distance'},
  'mae': 77.25801122256406},
 '4905_fourier': {'best_par': {'metric': 'minkowski',
   'n_neighbors': 24,
   'weights': 'uniform'},
  'mae': 610.8769965277778},
 'time': 1.47}
Jorge L.
  • 116
  • 5
-2

It's quite straightforward.

for v in data.values():
    if isinstance(v,dict):
        v['best_par']['n_neighbors'] = int(v['best_par']['n_neighbors'])

This assumes you don't really need to troll through the deep structure LOOKING for such values. That's harder.

Tim Roberts
  • 48,973
  • 4
  • 21
  • 30