4 votes

Convertir une colonne pandas contenant un dictionnaire en plusieurs lignes

J'ai ce Dataframe

temp = pd.DataFrame({'Person': ['P1', 'P2'], 'Dictionary': [{'value1': 0.31, 'value2': 0.304}, {'value2': 0.324}]})

  Person                    Dictionary    
0  P1  {'value1': 0.31, 'value2': 0.304}
1  P2                  {'value2': 0.324}

Je veux une sortie dans ce format :

temp1 = pd.DataFrame({'Person': ['P1', 'P1', 'P2'], 'Values_Number': ['value1', 'value2', 'value2'], 'Values': [0.31, 0.304, 0.324]})

J'ai essayé d'utiliser ceci :

temp['Dictionary'].apply(pd.Series).T.reset_index()

  Person Values_Number  Values
0     P1        value1   0.310
1     P1        value2   0.304
2     P2        value2   0.324

Mais je ne suis pas en mesure de concaténer ce dernier avec le Dataframe précédent. De plus, il y aurait des risques d'erreur.

5voto

ansev Points 26199

IIUC, Nous pourrions utiliser Series.tolist afin de construire un nouveau DataFrame que nous pouvons melt avec DataFrame.melt

new_df = (pd.DataFrame(temp['Dictionary'].tolist(), index=temp['Person'])
            .reset_index()
            .melt('Person', var_name='Values_Number', value_name='Values')
            .dropna()
            .reset_index(drop=True))
print(new_df)

  Person Values_Number  Values
0     P1        value1   0.310
1     P1        value2   0.304
2     P2        value2   0.324

il est beaucoup plus efficace d'utiliser pd.DataFrame(df['Dictionary'].tolist()) que .apply(pd.Series) . Vous pouvez voir quand vous devez utiliser apply dans votre code here


C'est le résultat pour apply(pd.Series) obtenus dans cette publication.

%timeit s.apply(pd.Series)
%timeit pd.DataFrame(s.tolist())

2.65 ms ± 294 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
816 µs ± 40.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

0voto

ksooklall Points 1992

Une combinaison de tolist y melt devrait fonctionner

pd.DataFrame(df['Dictionary'].tolist()).set_index(temp['per']).reset_index().melt(id_vars='Person', value_vars=['value1', 'value2'], var_name='Values_Number').dropna()

  Person Values_Number  value
0  P1    value1         0.310
2  P1    value2         0.304
3  P2    value2         0.324

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X