3 votes

la façon la plus efficace de mettre à jour les données pandas lorsque l'index ne correspond pas

J'ai deux DataFrames pandas et je veux mettre à jour l'une avec l'autre... Mais je ne peux pas être sûr que les index correspondent. (c'est donc un problème d'utiliser DataFrame.update !)

exemple :

import pandas as pd
df1 = pd.DataFrame([('path1', 0, 0, 0),
                    ('path2', 0, 0, 0),
                    ('path3', 0, 0, 0),
                    ('path4', 0, 0, 0),],
                  columns=['path', 'class', 'manual', 'conf'],
                  index = [1,2,3,4])

df2 = pd.DataFrame([('path1', 1, 0, 0),
                    ('path2', 0, 1, 0),
                    ('path3', 0, 0, 1),
                    ('path5', 1, 1, 0),
                    ('path6', 1, 1, 0),],
                  columns=['path', 'class', 'manual', 'conf'],
                  index = [10,11,12,13,14])

Le résultat souhaité :

update_annotations(df1, df2)

    path  class  manual  conf
1  path1      1       0     0
2  path2      0       1     0
3  path3      0       0     1
4  path4      0       0     0

df1.update(df2) peut être risqué, car les index de ces données peuvent ne pas correspondre. quelle est la manière la plus sûre et la plus efficace de procéder ?

4voto

piRSquared Points 159

Vite fait, bien fait

df1[['path']].merge(df2, 'left')

    path  class  manual  conf
0  path1    1.0     0.0   0.0
1  path2    0.0     1.0   0.0
2  path3    0.0     0.0   1.0
3  path4    NaN     NaN   NaN

Moins rapide et moins sale

df1[['path']].merge(df2, 'left').fillna(0).astype(df1.dtypes)

    path  class  manual  conf
0  path1      1       0     0
1  path2      0       1     0
2  path3      0       0     1
3  path4      0       0     0

Pédant

Remplissage NaN con df1

df1[['path']].merge(df2, 'left').fillna({**df1}).astype(df1.dtypes)

    path  class  manual  conf
0  path1      1       0     0
1  path2      0       1     0
2  path3      0       0     1
3  path4      0       0     0

Par Chris

df1.set_index('path').assign(**df2.set_index('path')).reset_index()

    path  class  manual  conf
0  path1    1.0     0.0   0.0
1  path2    0.0     1.0   0.0
2  path3    0.0     0.0   1.0
3  path4    NaN     NaN   NaN

Conserver l'index

Puisque l'ordre est garanti identique, nous pouvons simplement utiliser set_index

df1[['path']].merge(df2, 'left').fillna({**df1}).astype(df1.dtypes).set_index(df1.index)

    path  class  manual  conf
1  path1      1       0     0
2  path2      0       1     0
3  path3      0       0     1
4  path4      0       0     0

1voto

Dror Hilman Points 150

Basé sur l'excellente réponse de piRSquared, La réponse que je cherchais :

df1 = (df1[['path']]
       .merge(df2, 'left')
       .set_index(df1.index)
       .fillna(df1))

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