Antecedentes
Tengo un objeto JSON anidado complejo, que estoy tratando de desempaquetar en un df de pandas de una manera muy específica.
Objeto JSON
este es un extracto que contiene datos aleatorios del objeto JSON, que muestra ejemplos de la jerarquía (incluidos los niños) para 1x familia (es decir, 'Falconer Family'), sin embargo, hay 100 de ellos en total y este extracto solo tiene 1x familia , sin embargo, el objeto JSON completo tiene múltiples:
{ "meta": { "columns": [{ "key": "value", "display_name": "Adjusted Value (No Div, USD)", "output_type": "Number", "currency": "USD" }, { "key": "time_weighted_return", "display_name": "Current Quarter TWR (USD)", "output_type": "Percent", "currency": "USD" }, { "key": "time_weighted_return_2", "display_name": "YTD TWR (USD)", "output_type": "Percent", "currency": "USD" }, { "key": "_custom_twr_audit_note_911328", "display_name": "TWR Audit Note", "output_type": "Word" } ], "groupings": [{ "key": "_custom_name_747205", "display_name": "* Reporting Client Name" }, { "key": "_custom_new_entity_group_453577", "display_name": "NEW Entity Group" }, { "key": "_custom_level_2_624287", "display_name": "* Level 2" }, { "key": "legal_entity", "display_name": "Legal Entity" } ] }, "data": { "type": "portfolio_views", "attributes": { "total": { "name": "Total", "columns": { "time_weighted_return": -0.046732301295604683, "time_weighted_return_2": -0.046732301295604683, "_custom_twr_audit_note_911328": null, "value": 23132492.905107163 }, "children": [{ "name": "Falconer Family", "grouping": "_custom_name_747205", "columns": { "time_weighted_return": -0.046732301295604683, "time_weighted_return_2": -0.046732301295604683, "_custom_twr_audit_note_911328": null, "value": 23132492.905107163 }, "children": [{ "name": "Wealth Bucket A", "grouping": "_custom_new_entity_group_453577", "columns": { "time_weighted_return": -0.045960317420568164, "time_weighted_return_2": -0.045960317420568164, "_custom_twr_audit_note_911328": null, "value": 13264448.506587159 }, "children": [{ "name": "Asset Class A", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": 0.000003434094574039648, "time_weighted_return_2": 0.000003434094574039648, "_custom_twr_audit_note_911328": null, "value": 3337.99 }, "children": [{ "entity_id": 10604454, "name": "HUDJ Trust", "grouping": "legal_entity", "columns": { "time_weighted_return": 0.000003434094574039648, "time_weighted_return_2": 0.000003434094574039648, "_custom_twr_audit_note_911328": null, "value": 3337.99 }, "children": [] }] }, { "name": "Asset Class B", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": -0.025871339096964152, "time_weighted_return_2": -0.025871339096964152, "_custom_twr_audit_note_911328": null, "value": 1017004.7192636987 }, "children": [{ "entity_id": 10604454, "name": "HUDG Trust", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.025871339096964152, "time_weighted_return_2": -0.025871339096964152, "_custom_twr_audit_note_911328": null, "value": 1017004.7192636987 }, "children": [] }] }, { "name": "Asset Class C", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": -0.030370376329670656, "time_weighted_return_2": -0.030370376329670656, "_custom_twr_audit_note_911328": null, "value": 231142.67772000004 }, "children": [{ "entity_id": 10604454, "name": "HKDJ Trust", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.030370376329670656, "time_weighted_return_2": -0.030370376329670656, "_custom_twr_audit_note_911328": null, "value": 231142.67772000004 }, "children": [] }] }, { "name": "Asset Class D", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": -0.05382756475465478, "time_weighted_return_2": -0.05382756475465478, "_custom_twr_audit_note_911328": null, "value": 9791282.570000006 }, "children": [{ "entity_id": 10604454, "name": "HUDW Trust", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.05382756475465478, "time_weighted_return_2": -0.05382756475465478, "_custom_twr_audit_note_911328": null, "value": 9791282.570000006 }, "children": [] }] }, { "name": "Asset Class E", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": -0.01351630404081805, "time_weighted_return_2": -0.01351630404081805, "_custom_twr_audit_note_911328": null, "value": 2153366.6396034593 }, "children": [{ "entity_id": 10604454, "name": "HJDJ Trust", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.01351630404081805, "time_weighted_return_2": -0.01351630404081805, "_custom_twr_audit_note_911328": null, "value": 2153366.6396034593 }, "children": [] }] }, { "name": "Asset Class F", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": -0.002298190175237247, "time_weighted_return_2": -0.002298190175237247, "_custom_twr_audit_note_911328": null, "value": 68313.90999999999 }, "children": [{ "entity_id": 10604454, "name": "HADJ Trust", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.002298190175237247, "time_weighted_return_2": -0.002298190175237247, "_custom_twr_audit_note_911328": null, "value": 68313.90999999999 }, "children": [] }] } ] }, { "name": "Wealth Bucket B", "grouping": "_custom_new_entity_group_453577", "columns": { "time_weighted_return": -0.04769870075659244, "time_weighted_return_2": -0.04769870075659244, "_custom_twr_audit_note_911328": null, "value": 9868044.398519998 }, "children": [{ "name": "Asset Class A", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": 0.000028632718065191298, "time_weighted_return_2": 0.000028632718065191298, "_custom_twr_audit_note_911328": null, "value": 10234.94 }, "children": [{ "entity_id": 10868778, "name": "2012 Desc Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": 0.0000282679297198829, "time_weighted_return_2": 0.0000282679297198829, "_custom_twr_audit_note_911328": null, "value": 244.28 }, "children": [] }, { "entity_id": 10643052, "name": "2013 Irrev Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": 0.000049373572795108345, "time_weighted_return_2": 0.000049373572795108345, "_custom_twr_audit_note_911328": null, "value": 5081.08 }, "children": [] }, { "entity_id": 10598341, "name": "Cht 11th Tr HBO Shirley", "grouping": "legal_entity", "columns": { "time_weighted_return": 0.000006609603754315074, "time_weighted_return_2": 0.000006609603754315074, "_custom_twr_audit_note_911328": null, "value": 1523.62 }, "children": [] }, { "entity_id": 10598337, "name": "Cht 11th Tr HBO Hannah", "grouping": "legal_entity", "columns": { "time_weighted_return": 0.000010999769004760296, "time_weighted_return_2": 0.000010999769004760296, "_custom_twr_audit_note_911328": null, "value": 1828.9 }, "children": [] }, { "entity_id": 10598334, "name": "Cht 11th Tr HBO Lau", "grouping": "legal_entity", "columns": { "time_weighted_return": 0.000006466673995619843, "time_weighted_return_2": 0.000006466673995619843, "_custom_twr_audit_note_911328": null, "value": 1557.06 }, "children": [] } ] }, { "name": "Asset Class B", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": -0.024645947842438676, "time_weighted_return_2": -0.024645947842438676, "_custom_twr_audit_note_911328": null, "value": 674052.31962 }, "children": [{ "entity_id": 10868778, "name": "2012 Desc Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.043304004172576405, "time_weighted_return_2": -0.043304004172576405, "_custom_twr_audit_note_911328": null, "value": 52800.96 }, "children": [] }, { "entity_id": 10643052, "name": "2013 Irrev Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.022408434778798836, "time_weighted_return_2": -0.022408434778798836, "_custom_twr_audit_note_911328": null, "value": 599594.11962 }, "children": [] }, { "entity_id": 10598341, "name": "Cht 11th Tr HBO Shirley", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.039799855483646174, "time_weighted_return_2": -0.039799855483646174, "_custom_twr_audit_note_911328": null, "value": 7219.08 }, "children": [] }, { "entity_id": 10598337, "name": "Cht 11th Tr HBO Hannah", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.039799855483646174, "time_weighted_return_2": -0.039799855483646174, "_custom_twr_audit_note_911328": null, "value": 7219.08 }, "children": [] }, { "entity_id": 10598334, "name": "Cht 11th Tr HBO Lau", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.039799855483646174, "time_weighted_return_2": -0.039799855483646174, "_custom_twr_audit_note_911328": null, "value": 7219.08 }, "children": [] } ] }, { "name": "Asset Class C", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": -0.03037038746301135, "time_weighted_return_2": -0.03037038746301135, "_custom_twr_audit_note_911328": null, "value": 114472.69744 }, "children": [{ "entity_id": 10868778, "name": "2012 Desc Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.030370390035505124, "time_weighted_return_2": -0.030370390035505124, "_custom_twr_audit_note_911328": null, "value": 114472.68744000001 }, "children": [] }, { "entity_id": 10643052, "name": "2013 Irrev Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": 0, "time_weighted_return_2": 0, "_custom_twr_audit_note_911328": null, "value": 0.01 }, "children": [] } ] }, { "name": "Asset Class D", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": -0.06604362523792162, "time_weighted_return_2": -0.06604362523792162, "_custom_twr_audit_note_911328": null, "value": 5722529.229999997 }, "children": [{ "entity_id": 10868778, "name": "2012 Desc Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.06154960593668424, "time_weighted_return_2": -0.06154960593668424, "_custom_twr_audit_note_911328": null, "value": 1191838.9399999995 }, "children": [] }, { "entity_id": 10643052, "name": "2013 Irrev Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.06750460387418267, "time_weighted_return_2": -0.06750460387418267, "_custom_twr_audit_note_911328": null, "value": 4416618.520000002 }, "children": [] }, { "entity_id": 10598341, "name": "Cht 11th Tr HBO Shirley", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.05604507809250081, "time_weighted_return_2": -0.05604507809250081, "_custom_twr_audit_note_911328": null, "value": 38190.33 }, "children": [] }, { "entity_id": 10598337, "name": "Cht 11th Tr HBO Hannah", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.05604507809250081, "time_weighted_return_2": -0.05604507809250081, "_custom_twr_audit_note_911328": null, "value": 37940.72 }, "children": [] }, { "entity_id": 10598334, "name": "Cht 11th Tr HBO Lau", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.05604507809250081, "time_weighted_return_2": -0.05604507809250081, "_custom_twr_audit_note_911328": null, "value": 37940.72 }, "children": [] } ] }, { "name": "Asset Class E", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": -0.017118805423322003, "time_weighted_return_2": -0.017118805423322003, "_custom_twr_audit_note_911328": null, "value": 3148495.0914600003 }, "children": [{ "entity_id": 10868778, "name": "2012 Desc Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.015251157805867277, "time_weighted_return_2": -0.015251157805867277, "_custom_twr_audit_note_911328": null, "value": 800493.06146 }, "children": [] }, { "entity_id": 10643052, "name": "2013 Irrev Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.01739609576880241, "time_weighted_return_2": -0.01739609576880241, "_custom_twr_audit_note_911328": null, "value": 2215511.2700000005 }, "children": [] }, { "entity_id": 10598341, "name": "Cht 11th Tr HBO Shirley", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.02085132265594647, "time_weighted_return_2": -0.02085132265594647, "_custom_twr_audit_note_911328": null, "value": 44031.21 }, "children": [] }, { "entity_id": 10598337, "name": "Cht 11th Tr HBO Hannah", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.02089393244695803, "time_weighted_return_2": -0.02089393244695803, "_custom_twr_audit_note_911328": null, "value": 44394.159999999996 }, "children": [] }, { "entity_id": 10598334, "name": "Cht 11th Tr HBO Lau", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.020607507059866248, "time_weighted_return_2": -0.020607507059866248, "_custom_twr_audit_note_911328": null, "value": 44065.39000000001 }, "children": [] } ] }, { "name": "Asset Class F", "grouping": "_custom_level_2_624287", "columns": { "time_weighted_return": -0.0014710489231547497, "time_weighted_return_2": -0.0014710489231547497, "_custom_twr_audit_note_911328": null, "value": 198260.12 }, "children": [{ "entity_id": 10868778, "name": "2012 Desc Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.0014477244560456848, "time_weighted_return_2": -0.0014477244560456848, "_custom_twr_audit_note_911328": null, "value": 44612.33 }, "children": [] }, { "entity_id": 10643052, "name": "2013 Irrev Tr HBO Thalia", "grouping": "legal_entity", "columns": { "time_weighted_return": -0.001477821083437858, "time_weighted_return_2": -0.001477821083437858, "_custom_twr_audit_note_911328": null, "value": 153647.78999999998 }, "children": [] } ] } ] } ] }] } }, "included": [] } } Notas sobre la extracción de objetos JSON
data : los datos aquí se pueden ignorar, estos son valores agregados para los niños subyacentes.meta - columns : contiene los valores de encabezado de columna que quiero usar para cada clave de 'columna' de children aplicable: valores de par.groupings - se pueden ignorar.children : hay 4 niveles de children que se pueden identificar por su name de la siguiente manera:name (es decir, 'Familia Falconer')name del depósito de riqueza (p. ej., 'Contenedor de riqueza A')name de clase de activo (p. ej., 'Clase de activo A')name del fondo (p. ej., 'HUDJ Trust') Salida objetivo
este es un extracto de la estructura df objetivo que estoy tratando de lograr:
| portafolio | nombre | entidad_id | Valor ajustado (sin división, USD) | Trimestre actual TWR (USD) | YTD TWR (USD) | Nota de auditoría de TWR |
|---|---|---|---|---|---|---|
| Familia cetrero | Familia cetrero | 23132492.90510712 | -0.046732301295604683 | -0.046732301295604683 | Ninguna | |
| Familia cetrero | Cubo de riqueza A | 13264448.506587146 | -0.045960317420568164 | -0.045960317420568164 | Ninguna | |
| Familia cetrero | Clase de activo A | 3337.99 | 0.000003434094574039648 | 0.000003434094574039648 | Ninguna | |
| Familia cetrero | Confianza HUDJ | 10604454 | 3337.99 | 0.000003434094574039648 | 0.000003434094574039648 | Ninguna |
| Familia cetrero | Clase de activo B | 1017004.7192636987 | -0.025871339096964152 | -0.025871339096964152 | Ninguna | |
| Familia cetrero | Fideicomiso de HUDG | 10604454 | 1017004.7192636987 | -0.025871339096964152 | -0.025871339096964152 | Ninguna |
| Familia cetrero | Clase de activo C | 231142.67772000004 | -0.030370376329670656 | -0.030370376329670656 | Ninguna | |
| Familia cetrero | Confianza de HKDJ | 10604454 | 231142.67772000004 | -0.030370376329670656 | -0.030370376329670656 | Ninguna |
| Familia cetrero | Clase de activo D | 9791282.570000006 | -0.05382756475465478 | -0.05382756475465478 | Ninguna | |
| Familia cetrero | Confianza HUDW | 10604454 | 9791282.570000006 | -0.05382756475465478 | -0.05382756475465478 | Ninguna |
Notas sobre la salida objetivo
name de los children de nivel superior [nombre de familia]. Ej., 'Familia Falconer'.name de cada children respectivo.children entity_id de 4.º nivel deben asignarse a esta columna.children elementos secundarios tienen columnas idénticas time_weighted_return , time-weighted_return2 y value que deben asignarse respectivamente._custom_twr_audit_note_911318 children actualmente en blanco, pero se utilizarán en el futuro. Salida de corriente
Mi problema principal es que puede ver que solo he podido aprovechar el primer nivel de children [Familia] y el segundo [Cubo de riqueza]. Esto me deja perdiendo la 3.ª [Clase de activo] y la 4.ª [Fondo] -
| portafolio | nombre | Valor ajustado (sin división, USD) | Trimestre actual TWR (USD) | YTD TWR (USD) | Nota de auditoría de TWR) | |
|---|---|---|---|---|---|---|
| 0 | Familia cetrero | Familia cetrero | 2.313249e+07 | -0.046732 | -0.046732 | Ninguna |
| 1 | Familia cetrero | Cubo de riqueza A | 1.326445e+07 | -0.045960 | -0.045960 | Ninguna |
| 2 | Familia cetrero | Cubo de riqueza B | 9.868044e+06 | -0.047699 | -0.047699 | Ninguna |
Código actual
Esta es una función que me da el formato df correcto, sin embargo, mi principal problema es que no he podido encontrar una solución para devolver todos los niños, sino solo el nivel superior:
# Function to read API response / JSON Object def response_writer(): with open('api_response_2022-02-13.json') as f: api_response = json.load(f) return api_response # Function to unpack JSON response into pandas dataframe. def unpack_response(): while True: try: api_response = response_writer() portfolio_views_children = api_response['data']['attributes']['total']['children'] portfolios = [] for portfolio in portfolio_views_children: entity_columns = [] # include portfolio itself within an iterable so the total is the header for entity in itertools.chain([portfolio], portfolio["children"]): entity_data = entity["columns"].copy() # don't mutate original response entity_data["portfolio"] = portfolio["name"] # from outer entity_data["name"] = entity["name"] entity_columns.append(entity_data) df = pd.DataFrame(entity_columns) portfolios.append(df) # combine dataframes df = pd.concat(portfolios) # reorder and rename column_ordering = {"portfolio": "portfolio", "name": "name"} column_ordering.update({c["key"]: c["display_name"] for c in api_response["meta"]["columns"]}) df = df[column_ordering.keys()] # beware: un-named cols will be dropped df = df.rename(columns=column_ordering) break except KeyError: print("-----------------------------------\n","API TIMEOUT ERROR: TRY AGAIN...", "\n-----------------------------------\n") return df unpack_response() Ayuda
En resumen, estoy buscando algunos consejos sobre cómo puedo aprovechar a los children restantes mejorando el código existente. Si bien me he tomado mucho tiempo para explicar completamente mi problema, por favor pregunte si algo no está claro. Tenga en cuenta que el JSON puede tener varias familias, por lo que la solución/consejo ofrecido debe observar esto
Creo que esto te acerca bastante; es posible que solo necesite ajustar las diversas columnas de name y soltar los datos adicionales (conservé la columna de grouping ).
La idea principal es usar pd.json_normalize de forma recursiva conpd.concat para todos children niveles secundarios disponibles.
EDITAR: coloque todo en una sola función y una sección agregada para colapsar las columnas de name como el resultado esperado.
def process_json(api_response): def get_column_values(df): return pd.concat([df, pd.json_normalize(df.pop('columns')).set_axis(df.index)], axis=1) def expand_children(df): if len(df.index) > 1: df['children'] = df['children'].fillna('').apply(lambda x: None if len(x) == 0 else x) df_children = df.pop('children').dropna().explode() if len(df_children.index) == 0: # return df if no children to append return df.index.names, df df_children = pd.json_normalize(df_children, max_level=0).set_axis(df_children.index).set_index('name', append=True) df_children = get_column_values(df_children) idx_names = list(df_children.index.names) idx_names[-1] = idx_names[-1] + '_' + str(len(idx_names)) df[idx_names[-1]] = None return idx_names, pd.concat([df.set_index(idx_names[-1], append=True), df_children], axis=0) columns_dict = pd.DataFrame(api_response['meta']['columns']).set_index('key').to_dict(orient='index') # save column definitions df = pd.DataFrame(api_response['data']['attributes']['total']['children']).set_index('name') # get initial dataframe df = get_column_values(df) # get columns for initial level # expand children while 'children' in df.columns: idx_names, df = expand_children(df) # reorder/replace column headers and sort index df = (df.loc[:, [x for x in df.columns if x not in columns_dict.keys()] + list(columns_dict.keys())] .rename(columns={k:v['display_name'] for k,v in columns_dict.items()}) .sort_index(na_position='first').reset_index()) #collapse "name" columns (careful of potential duplicate rows) for col in idx_names[::-1]: df[idx_names[-1]] = df[idx_names[-1]].fillna(df[col]) df = df.rename(columns={'name': 'portfolio', idx_names[-1]: 'name'}).drop(columns=idx_names[1:-1]) return df Dado que la otra respuesta usa iterrows , que generalmente no se recomienda, pensé que valía la pena una comparación rápida.
process_json(api_response) 54.2 ms ± 7.12 ms per loop (mean ± std. dev. of 7 runs, 10 loops each) unpack_response(api_response) # iterrows 84.3 ms ± 9.04 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)Su problema es que tiene 3 capas de niños 'anidados' dentro de un json. Desea cargarlos a todos en pandas y des-anidarlos ( explode ) en pandas , no manualmente en un bucle for externo.
Desafío: al explotar, cada hijo tiene a su vez un campo llamado name , que ya existe en el padre hijo. Por lo tanto, debemos cambiarles el nombre mientras hacemos las sucesivas explosiones (como lo hizo en su pregunta original, por ejemplo, 'cartera' en realidad se llama 'nombre' en el json). Finalmente, todos los demás valores guardados en la información de las columns se pueden unpack .
Ejemplo de trabajo completo:
import pandas as pd import json # get the json file json_dict = json.load(open('api_response_2022-02-13.json')) # create a (nested) df out of it, and rename the 'top-level' name field to 'portfolio' packed_df = pd.DataFrame.from_dict(json_dict['data']['attributes']['total']['children'])\ .rename(columns={'name': 'portfolio'}) # expand the level-1 'children' (and call their 'name' field 'grand-parent') unpacked_df = packed_df.groupby('portfolio')['children']\ .apply(lambda x: pd.DataFrame(x.values[0])).reset_index()\ .rename(columns={'name': 'grand_parent_name'}) # expand the level-2 'children' (and call their 'name' field 'parent') unpacked_df = unpacked_df.groupby(['portfolio', 'grand_parent_name'])['children']\ .apply(lambda x: pd.DataFrame(x.values[0])).reset_index()\ .rename(columns={'name': 'parent_name'}) # expand the level-3 'children' (and keep their name as is) unpacked_df = unpacked_df.groupby(['portfolio', 'grand_parent_name', 'parent_name'])['children']\ .apply(lambda x: pd.DataFrame(x.values[0])).reset_index() # expand the column field info from 'dict' to multiple columns unpacked_df = pd.concat([unpacked_df.drop('columns', axis=1), pd.DataFrame(unpacked_df['columns'].tolist())], axis=1)Por supuesto, puede poner los 3 pasos recursivos de desempaquetado en una función separada, pero los mantuvo separados aquí para mayor claridad (en realidad está desempaquetando diferentes jerarquías de 'hijos' y necesita cuidar cada 'nombre ' por separado)
Al final, tiene todas las columnas de los 3 niveles jerárquicos (todos los json en un df): renómbrelos, elimine algunos de ellos, como desee. Para su resultado final, su captura de pantalla ya mezcla los diferentes niveles de name ("Wealth Bucket A/B" no está en el mismo nivel que "HUDW/HADJ Trust")