――Je souhaite développer un dictionnaire imbriqué en le connectant avec un trait de soulignement.
--Entrée: d1 = {'A': {'i': 0, 'j': 1}, 'B': {'i': 2, 'j': 3}}
Données pouvant être stockées dans un dictionnaire
d2 = {'A_i': 0, 'A_j': 1, 'B_i': 2, 'B_j': 3}
, ouvrir les données dans une dimension――A la fin, le dictionnaire imbriqué a une structure arborescente. En tant qu'image, le processus est comme briser une structure arborescente et relier directement les racines et les extrémités. --Une fonction récursive semble être bonne pour l'implémenter comme une recherche de priorité en profondeur
J'ai donc écrit le code suivant.
#changement clé
def changekey(dict,k1,k2):
dict[k2] = dict[k1]
del dict[k1]
#Ajouter des modificateurs à toutes les clés avec des traits de soulignement
def addkeyheader(dict,key):
ks = list(dict.keys())
for k in ks:
changekey(dict,k,key+'_'+k)
#Fonction favorite Après avoir effectué une recherche de priorité de profondeur, combinez les noms d'éléments et
def dict_flatten(dict_,depth=2):
newdict = {}
for key in list(dict_.keys()):
#Si l'élément est également dict, appelez-le récursivement
if isinstance(dict_[key], dict):
if depth > 0:
dic = dict_flatten(dict_[key],depth-1)
addkeyheader(dic,key)
newdict.update(dic)
else:
newdict[key] = dict_[key]
#Si l'élément n'est pas dict, laissez-le tel quel
else:
newdict[key] = dict_[key]
return newdict
Dans les commentaires, je vous ai parlé d'une mise en œuvre plus intelligente.
def _unwrap(dct, prefix):
for key, value in dct.items():
new_key = f'{prefix}_{key}'
if isinstance(value, dict):
yield from _unwrap(value, new_key)
else:
yield new_key[1:], value
def unwrap(dct):
return dict(_unwrap(dct, ''))
d2 = unwrap(d1)
--Le dict imbriqué est organisé en deux dimensions comme indiqué ci-dessous (Référence).
Lorsque l'entrée est convertie, cela devient comme suit.
>> pd.DataFrame.from_dict(d1)
A B
i 0 2
j 1 3
La sortie est convertie comme suit.
>> pd.DataFrame(d2,index=[""])
A_i A_j B_i B_j
0 1 2 3
J'ai trouvé que c'était une bonne idée, mais je ne comprenais pas très bien les pandas.
En pratique, il peut être édité avec la fonction MultiIndex sans avoir à le démonter. https://qiita.com/Morinikiz/items/40faa91e7a83807c0552
--Il peut être résumé par stacking () ou unstack () df. --La pile peut mettre le côté de la colonne à un niveau élevé, le désempilage peut mettre le côté de la ligne à un niveau élevé ――Cependant, pourquoi le comportement est-il opposé à Explication ici?
>>> df = pd.DataFrame(d1)
>>> df
A B
i 0 2
j 1 3
>>> df.unstack()
A i 0
j 1
B i 2
j 3
dtype: int64
>>> df.stack()
i A 0
B 2
j A 1
B 3
dtype: int64
Pour revenir au bloc de données, utilisez to_frame () à la fin.
>>> df.unstack().to_frame("name")
name
A i 0
j 1
B i 2
j 3
Recommended Posts