Je tente une fusion entre deux trames de données. Chaque bloc de données a deux niveaux d'index (date, cusip). Dans les colonnes, certaines colonnes correspondent entre les deux (devise, date d'aj) par exemple.
Quelle est la meilleure façon de les fusionner par index, mais de ne pas prendre deux copies de la devise et de la date adj.
Chaque trame de données compte 90 colonnes, j'essaie donc d'éviter de tout écrire à 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! ...
J'utilise l'
suffixes
option dans.merge()
:dfNew = df.merge(df2, left_index=True, right_index=True, how='outer', suffixes=('', '_y')) dfNew.drop(dfNew.filter(regex='_y$').columns.tolist(),axis=1, inplace=True)
Merci @ijoseph
la source
filter
ing (ce qui est assez simple, mais prend encore beaucoup de temps à rechercher / sujet aux erreurs à retenir). iedfNew.drop(list(dfNew.filter(regex='_y$')), axis=1, inplace=True)
Je suis fraîchement nouveau avec Pandas mais je voulais réaliser la même chose, en évitant automatiquement les noms de colonne avec _x ou _y et en supprimant les données en double. Je l'ai finalement fait en utilisant cette réponse et celle- ci de Stackoverflow
sales.csv
revenue.csv
merge.py importer des pandas
def drop_y(df): # list comprehension of the cols that end with '_y' to_drop = [x for x in df if x.endswith('_y')] df.drop(to_drop, axis=1, inplace=True) sales = pandas.read_csv('data/sales.csv', delimiter=';') revenue = pandas.read_csv('data/revenue.csv', delimiter=';') result = pandas.merge(sales, revenue, how='inner', left_on=['state'], right_on=['state_id'], suffixes=('', '_y')) drop_y(result) result.to_csv('results/output.csv', index=True, index_label='id', sep=';')
Lors de l'exécution de la commande de fusion, je remplace le
_x
suffixe par une chaîne vide et je peux supprimer les colonnes se terminant par_y
output.csv
la source
En vous basant sur la réponse de @ rprog, vous pouvez combiner les différentes parties de l'étape de suffixe et de filtre en une seule ligne en utilisant une expression régulière négative:
dfNew = df.merge(df2, left_index=True, right_index=True, how='outer', suffixes=('', '_DROP')).filter(regex='^(?!.*_DROP)')
Ou en utilisant
df.join
:dfNew = df.join(df2),lsuffix="DROP").filter(regex="^(?!.*DROP)")
Le regex ici garde tout ce qui ne se termine pas par le mot "DROP", alors assurez-vous simplement d'utiliser un suffixe qui n'apparaît pas déjà parmi les colonnes.
la source