189 votes

Fusion de Pandas - Comment éviter de dupliquer des colonnes

Je tente une fusion entre deux data frames. Chaque data frame a deux niveaux d'index (date, cusip). Dans les colonnes, certaines colonnes correspondent entre les deux (devise, date ajustée) par exemple.

Quel est le meilleur moyen de fusionner ceux-ci par index, mais sans prendre deux copies de la devise et de la date ajustée.

Chaque data frame a 90 colonnes, donc j'essaie d'éviter d'écrire tout à la main.

df:                 currency  adj_date   data_col1 ...
date        cusip
2012-01-01  XSDP      USD      2012-01-03   0.45
...

df2:                currency  adj_date   data_col2 ...
date        cusip
2012-01-01  XSDP      USD      2012-01-03   0.45
...

Si je fais :

dfNew = merge(df, df2, left_index=True, right_index=True, how='outer')

Je reçois

dfNew:              currency_x  adj_date_x   data_col2 ... currency_y adj_date_y
date        cusip
2012-01-01  XSDP      USD      2012-01-03   0.45             USD         2012-01-03

Merci! ...

3voto

grisaitis Points 112

Si les index sont les mêmes (gros if vrai !), vous pouvez faire :

df = df1.copy()
df[df2.columns] = df2

similaire à merge

pd.merge(df1, df2, index_left=True, index_right=True)

mais sans colonnes en double

2voto

FinkAvenue Points 579

Vous pouvez supprimer les colonnes dupliquées y que vous ne voulez pas après la jointure:

# Joindre df et df2
dfNew = merge(df, df2, left_index=True, right_index=True, how='inner')

Sortie: currency_x | adj_date_x | data_col1 | ... | currency_y | adj_date_y | data_col2

# Supprimer les colonnes y en sélectionnant les colonnes que vous voulez conserver
dfNew = dfNew.loc[:, ("currency_x", "adj_date_x", "data_col1", "data_col2")]

Sortie: currency_x | adj_date_x | data_col1 | data_col2

0voto

user6046760 Points 70

Ne pouvez-vous pas simplement obtenir un sous-ensemble des colonnes dans l'un ou l'autre des df d'abord?

[i for i in df.columns if i not in df2.columns]

dfNew = merge(df **[i for i in df.columns if i not in df2.columns]**, df2, left_index=True, right_index=True, how='outer')

0voto

Lorsque le nombre de colonnes que vous voulez éviter est inférieur au nombre de colonnes que vous voulez garder... vous pouvez utiliser ce type de filtrage :

df.loc[:, ~df.columns.isin(['currency', 'adj_date'])]

Cela filtrera toutes les colonnes du dataframe sauf les colonnes 'currency' et 'adj_date', vous devez écrire la fusion quelque chose comme ceci :

    dfNew = merge(df, 
                  df2.loc[:, ~df.columns.isin(['currency', 'adj_date'])], 
                  left_index=True,
                  right_index=True,
                  how='outer')

Notez le "~", cela signifie "non".

0voto

Till Hoffmann Points 619

Vous pouvez inclure des colonnes dupliquées dans la clé de fusion pour garantir qu'une seule copie apparaît dans le résultat.

# Générer des données factices.
shared = pd.DataFrame({'key': range(5), 'name': list('abcde')})
a = shared.copy()
a['value_a'] = np.random.normal(0, 1, 5)
b = shared.copy()
b['value_b'] = np.random.normal(0, 1, 5)

# Fusion standard.
merged = pd.merge(a, b, on='key')
print(merged.columns)  # Index(['key', 'name_x', 'value_a', 'name_y', 'value_b'], dtype='object')

# Fusion avec les deux clés.
merged = pd.merge(a, b, on=['key', 'name'])
print(merged.columns)  # Index(['key', 'name', 'value_a', 'value_b'], dtype='object')

Cette méthode garantit également que les valeurs des colonnes présentes dans les deux cadres de données sont cohérentes (par exemple, que la devise dans les deux colonnes est la même). Si ce n'est pas le cas, la ligne correspondante sera supprimée (si how = 'inner') ou apparaîtra avec des valeurs manquantes (si how = 'outer').

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