Keep pandas dataframe for nested dict by splitting keys and decrementing values

Trying to convert pandas DataFrame to dictionary. pandas The to_dict

parameterized utility is orient

apparently not sufficient for this case. In some cases, my current code works.

Questions: 1. Any suggestions for changing the current code to make it look elegant and possibly faster? 2. How to add recursion to this script to make it work for an arbitrary nesting level.

fs = {'b1':{'f:ban':6, 'f:app':4}, 'b2':{'f:ban':4, 'f:app':2}}
dF = pandas.DataFrame.from_dict(fs, orient='index')
pandas.DataFrame.to_dict(dF, orient='index')
>>>{'b1': {'f:app': 4, 'f:ban': 6}, 'b2': {'f:app': 2, 'f:ban': 4}}

      

I want this store like this, paginating keys and grouping / decrementing values:

{'b1': {'f': {'app': 4, 'ban': 6}}, 'b2': {'f': {'app': 2, 'ban': 4}}

      

My code works for this nesting level, however there might be a concise way to do it.

Original dictionary:

fruits = {'b1': {'f:app': 4, 'f:ban': 6}, 'b2': {'f:app': 2, 'f:ban': 4}}

      

First, define a helper function to create a nested dictionary from a flat list:

def create_nested_dict(L):
    if len(L) == 2:
        return {L[0]:L[1]}
    while len(L) > 2:
        d = {}
        key = L[0]
        L = L[1:]
        d.update({key:create_nested_dict(L)})
        return d

L = ['f', 'app','4']
create_nested_dict(L)
>>> {'f': {'app': '4'}}

      

Then use the above function

new_fruits = {}
for key in fruits.keys():
    _d = {key:{}}
    for k,v in fruits[key].items():
        L = k.split(':')
        N = create_nested_dict(L + [v])
        if list(N)[0] in list(_d[key]):
            _d[key][list(N)[0]].update(N[list(N)[0]])
        else:
            _d[key].update(N)
new_fruits.update(_d)

print (new_fruits)
>>> {'b1': {'f': {'app': 4, 'ban': 6}}, 'b2': {'f': {'app': 2, 'ban': 4}}}

      

My code is not suitable for the following cases. Note the extra nesting level

fruits = {'b1': {'f:app:sim': 4, 'f:app:del': 3, 'f:ban:del': 6}, 'b2': {'f:app:sim': 2, 'f:app:del': 5, 'f:ban:del': 4}}
>>> {'b1': {'f': {'app': {'sim': 4}, 'ban': {'del': 6}}}, 'b2': {'f': {'app': {'sim': 2}, 'ban': {'del': 4}}}}

      

One key pair is missing: value ... {'app': {'del': 3}, ..

+3


source to share


1 answer


Here's a recursive approach to your problem:

First , convert the keys of the nested dictionary to a recursive nesting function. It tuplize

just creates a new dictionary with key strings instead of delimited strings :

:

fruits = {'b1': {'f:app:sim': 4, 'f:app:del': 3, 'f:ban:del': 6}, 
          'b2': {'f:app:sim': 2, 'f:app:del': 5, 'f:ban:del': 4}}

def tuplize(to_tuplize):
    return {tuple(keys.split(":")): value 
            for keys, value in to_tuplize.items()}

tupled = tuplize(fruits["b1"])
print(tupled)

>>> {('f', 'ban', 'del'): 6, ('f', 'app', 'sim'): 4, ('f', 'app', 'del'): 3}

      

Second , process each element tupled

recursively as shown in nest_dict

. How it works is very simple:

  • If there is only one key left in your alternating keychain, set the value.
  • Rest, pass the remaining keychain to the recursive function under the current key and handle the possibility of the existing key.


What is it.

def nest_dict(to_nest, nested=None):
    if nested is None:
        nested = {}

    for keys, value in to_nest.items():
        first_key = keys[0]
        if len(keys)== 1:
            nested[first_key] = value
            continue

        if first_key in nested:
            nest_dict({keys[1:]: value}, nested[first_key])
        else:
            nested[first_key] = nest_dict({keys[1:]: value})

    return nested

print(nest_dict(tupled))
>>> {'f': {'app': {'del': 3, 'sim': 4}, 'ban': {'del': 6}}}

      

Finally, you can use both helper functions in combination with dictionary comprehension to get the format you want:

result = {key: nest_dict(tuplize(value))
          for key, value in fruits.items()}
print(result)

>>> {'b1': {'f': {'app': {'del': 3, 'sim': 4}, 'ban': {'del': 6}}},
     'b2': {'f': {'app': {'del': 5, 'sim': 2}, 'ban': {'del': 4}}}}

      

+1


source







All Articles