Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

143
Vistas
¿Cómo unir dos marcos de datos cuando solo algunas fechas en un marco de datos están presentes entre otras dos fechas en otro marco de datos?

Tengo dos marcos de datos:

 df_A = pd.DataFrame({'start_date':['2021-04-01 00:00:00','2021-05-01 00:00:00', '2021-05-02 00:00:00'],'end_date':['2021-04-01 00:11:00','2021-05-01 00:06:00', '2021-05-03 00:00:00'], 'eventname':['birthday', 'wedding', 'birthday'] }) df_B = pd.DataFrame({'event_date':['2021-04-01 00:06:00','2021-05-01 00:03:00', '2021-05-04 00:00:00'],'price':[100,200,500]}) df_A['end_date'] = pd.to_datetime(df_A.end_date) df_A['start_date'] = pd.to_datetime(df_A.start_date) df_B['event_date'] = pd.to_datetime(df_B.event_date) df_A start_date end_date eventname 0 2021-04-01 2021-04-01 00:11:00 birthday 1 2021-05-01 2021-05-01 00:06:00 wedding 2 2021-05-02 2021-05-03 00:00:00 birthday df_B event_date price 0 2021-04-01 00:06:00 100 1 2021-05-01 00:03:00 200 2 2021-05-04 00:00:00 500

Quiero unirme a ellos de manera que la columna event_date se encuentre entre la columna start_date y end_date de df_A. Este es mi código:

 df_A.index = pd.IntervalIndex.from_arrays(df_A['start_date'],df_A['end_date'],closed='both') df_B['start_date'] = df_B['event_date'].apply(lambda x : df_A.iloc[df_A.index.get_loc(x)]['start_date']) df_B

Sin embargo, recibo un error de clave ya que algunos de los valores en la columna event_date de df_B no se encuentran entre ninguna de las columnas start_date y end_date de df_A.

Este es mi resultado esperado:

 event_date price start_date 0 2021-04-01 00:06:00 100 2021-04-01 1 2021-05-01 00:03:00 200 2021-05-01 2 2021-05-04 00:00:00 500 NaN

Intenté usar la intersección, pero eso solo funciona si los valores son exactamente iguales. ¿Cómo hago esto?

over 4 years ago · Santiago Trujillo
2 Respuestas
Responde la pregunta

0

Si su start_date y end_date no se superponen, cree un índice de intervalo y combine sus dos marcos de datos:

 bins = pd.IntervalIndex.from_arrays(df_A['start_date'], df_A['end_date'], closed='both') out = df_B.assign(interval=pd.cut(df_B['event_date'], bins)) \ .merge(df_A.assign(interval=bins), on='interval', how='left') print(out[['event_date', 'price', 'start_date']]) # Output: event_date price start_date 0 2021-04-01 00:06:00 100 2021-04-01 1 2021-05-01 00:03:00 200 2021-05-01 2 2021-05-04 00:00:00 500 NaT
over 4 years ago · Santiago Trujillo Denunciar

0

Si puede evitar una combinación no equitativa, hágalo; use una técnica de agrupamiento, similar a la excelente respuesta de @Corralien, donde los contenedores no se superponen (más rápido/más eficiente). Otra opción, si es posible, es encontrar una manera de introducir uniones de fusión, y tal vez unir su resultado final -> los pasos pueden ser más largos, sin embargo, creo que si se hace bien, sería más eficiente que una unión no equi. Sin embargo, si solo le interesa la primera coincidencia, pd.merge_asof debería ser suficiente.

Volviendo a la pregunta:

Una opción es a través de conditional_join de pyjanitor :

 # pip install pyjanitor import pandas as pd import janitor (df_A.conditional_join( df_B, # column from left frame, column from right frame, comparision operator ('start_date', 'event_date', '<='), ('end_date', 'event_date', '>='), how = 'right') .filter(['event_date', 'price', 'start_date']) ) event_date price start_date 0 2021-04-01 00:06:00 100 2021-04-01 1 2021-05-01 00:03:00 200 2021-05-01 2 2021-05-04 00:00:00 500 NaT

Lo que hace es comparar columnas de df_A con df_B :

('start_date', 'event_date', '<=') significa verificar si start_date de df_A es <= event_date de df_B . mismo concepto se aplica a las otras condiciones. El parámetro aquí es argumentos variables, lo que significa que puede pasar tantas condiciones como sea posible. Las columnas deben ser del mismo tipo (flotante frente a flotante, entero frente a entero, fecha frente a fecha, ...).

Debajo del capó, utiliza la búsqueda binaria para uniones no equitativas (principalmente para evitar una unión cartesiana, que puede ser ineficiente en términos de memoria a medida que crece el tamaño del marco de datos); para uniones de rango como en este caso, utiliza una búsqueda simple para reducir el espacio de búsqueda para obtener las filas coincidentes.

La función puede manejar índices superpuestos, así como escenarios en los que la combinación de rango involucra dos columnas diferentes -> a < b and c > d .

Puedes echar un vistazo a más ejemplos aquí

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda