J'ai deux Pandas DataFrames qui ont des données similaires mais incomplètes. Il s'agit principalement de données relatives aux pays, voici donc quelques exemples de fausses données Population (millions) :
Tableau A
| Country | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | |--------:|------|------|------|------|------|------| | USA | 319 | 321 | 323 | 325 | 328 | 330 | | UK | 58 | 60 | nan | 63 | 65 | 68 | | India | 780 | 810 | 820 | nan | 1100 | 1300 | | China | nan | nan | 1100 | 1200 | 1300 | nan | | Nigeria | 90 | 100 | 105 | nan | nan | 110 |
Je veux donc les combiner de telle sorte que les nan soient remplis à partir du tableau B s'ils existent, et des colonnes et des lignes sont ajoutées si elles ne sont pas là. S'il y a un conflit, je me fiche de celui qui est utilisé (les différences ne sont pas assez significatives).
En gros, j'aimerais qu'un résultat ressemble à ceci (dans ce cas, les valeurs de la table B sont utilisé en cas d'égalité):
Table A union Table B
| Country | 2014 | 2015 | 2016 | 2017 | 2018 | |--------:|------|------|------|------|------| | USA | nan | nan | 323 | 325 | 328 | | UK | nan | nan | nan | 63 | 65 | | India | nan | nan | 800 | nan | 1100 | | China | nan | nan | 1100 | 1200 | 1300 |
Intuitivement, je veux juste le tableau le plus complet possible . Existe-t-il un moyen de le faire sans avoir à exécuter une boucle for? La table est grande et je ne veux pas avoir à écrire une longue boucle.
3 Réponses :
Vous pouvez utiliser concat et groupby:
Country 2014 2015 2016 2017 2018 2019 0 USA 319.0 321.0 323.0 325.0 328.0 330.0 1 UK 58.0 60.0 NaN 63.0 65.0 68.0 2 India 780.0 810.0 800.0 NaN 1100.0 1300.0 3 China NaN NaN 1100.0 1200.0 1300.0 NaN 4 Nigeria 90.0 100.0 105.0 NaN NaN 110.0
Output:
(pd.concat([df1,df2], sort=False)
.groupby('Country', sort=False,as_index=False)
.agg('first')
)
J'ai vu des réponses comme ça, mais qu'en est-il des lignes manquantes du tableau A comme le Nigeria?
De plus, cela ne résout pas le problème où le tableau A a également des colonnes manquantes (comme 2019), il ne remplit que le tableau A.
@QuantumHoneybees désolé, n'a pas remarqué cette partie. Actualisé
Utiliser :
df_join=( df2.merge(df1,how='outer')
.groupby('Country')
.apply(lambda x: x.ffill().bfill())
.drop_duplicates('Country') )
print(df_join)
Country 2014 2015 2016 2017 2019 2018
0 USA 319.0 321.0 324.0 325.0 330.0 328.0
1 UK 58.0 60.0 NaN 63.0 68.0 65.0
2 India 780.0 810.0 820.0 NaN 1300.0 1100.0
3 Nigeria 90.0 100.0 105.0 NaN 110.0 NaN
7 China NaN NaN 1100.0 1200.0 NaN 1300.0
Vous pouvez faire:
Year 2014 2015 2016 2017 2018 2019 Country China NaN NaN 1100.0 1200.0 1300.0 NaN India 780.0 810.0 810.0 NaN 1100.0 1300.0 Nigeria 90.0 100.0 105.0 NaN NaN 110.0 UK 58.0 60.0 NaN 63.0 65.0 68.0 USA 319.0 321.0 323.5 325.0 328.0 330.0
Sortie
result = pd.concat([A.melt(id_vars='Country', var_name='Year', value_name='Population'),
B.melt(id_vars='Country', var_name='Year', value_name='Population')]).dropna()
print(pd.crosstab(index=result.Country, columns=result.Year, values=result.Population, aggfunc='mean'))