Estoy intentando una fusión entre dos marcos de datos. Cada marco de datos tiene dos niveles de índice (fecha, cúspide). En las columnas, algunas columnas coinciden entre las dos (moneda, fecha de ajuste), por ejemplo.
¿Cuál es la mejor manera de fusionarlos por índice, pero no tomar dos copias de moneda y fecha de ajuste?
Cada marco de datos tiene 90 columnas, por lo que estoy tratando de evitar escribir todo a mano.
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 lo hago:
dfNew = merge(df, df2, left_index=True, right_index=True, how='outer')
yo obtengo
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
¡Gracias! ...
Yo uso la
suffixes
opción en.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)
Gracias @ijoseph
fuente
filter
ing (que es bastante sencillo, pero aún requiere mucho tiempo de búsqueda / propenso a errores de recordar). iedfNew.drop(list(dfNew.filter(regex='_y$')), axis=1, inplace=True)
Soy nuevo con Pandas, pero quería lograr lo mismo, evitando automáticamente los nombres de columna con _x o _y y eliminando datos duplicados. Finalmente lo hice utilizando esta respuesta y esto uno de Stackoverflow
sales.csv
ingresos.csv
merge.py importar 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=';')
Al ejecutar el comando de fusión, reemplazo el
_x
sufijo con una cadena vacía y puedo eliminar las columnas que terminan con_y
output.csv
fuente
Sobre la base de la respuesta de @ rprog, puede combinar las diversas piezas del sufijo y el paso de filtro en una línea usando una expresión regular negativa:
dfNew = df.merge(df2, left_index=True, right_index=True, how='outer', suffixes=('', '_DROP')).filter(regex='^(?!.*_DROP)')
O usando
df.join
:dfNew = df.join(df2),lsuffix="DROP").filter(regex="^(?!.*DROP)")
La expresión regular aquí guarda todo lo que no termine con la palabra "DROP", así que asegúrese de usar un sufijo que no aparezca entre las columnas.
fuente