¿Cómo hacer coincidir varias columnas en el dataframe de pandas para un “intervalo”?

Tengo el siguiente dataframe de pandas:

import pandas as pd df = pd.DataFrame('filename.csv') print(df) order start end value 1 1342 1357 category1 1 1459 1489 category7 1 1572 1601 category23 1 1587 1599 category2 1 1591 1639 category1 .... 15 792 813 category13 15 892 913 category5 .... 

Por lo tanto, hay una columna de order que abarca muchas filas cada una, y luego un rango / intervalo de start a end para cada fila. Cada fila se etiqueta con un cierto value (por ejemplo, categoría 1, categoría 2, etc.)

Ahora tengo otro dataframe llamado key_df . Es básicamente el mismo formato exacto:

 import pandas as pd key_df = pd.DataFrame(...) print(key_df) order start end value 1 1284 1299 category4 1 1297 1309 category9 1 1312 1369 category3 1 1345 1392 category29 1 1371 1383 category31 .... 1 1471 1501 category31 ... 

Mi objective es tomar el key_df key_df y verificar si los intervalos start:end con alguna de las filas en el df dataframe original. Si lo hace, esta fila en df debe estar etiquetada con el value key_df dataframe.

En nuestro ejemplo anterior, el dataframe df terminaría así:

 order start end value key_value 1 1342 1357 category1 category29 1 1459 1489 category7 category31 .... 

Esto es porque si nos fijamos en key_df , la fila

 1 1345 1392 category29 

con el intervalo 1::1345-1392 cae en el intervalo 1::1342-1357 en el df original. Igualmente, la fila key_df :

 1 1471 1501 category31 

corresponde a la segunda fila en df :

 1 1459 1489 category7 category31 

No estoy del todo seguro

(1) Cómo realizar esta tarea en pandas.

(2) cómo escalar esto eficientemente en pandas

Se podría comenzar con una sentencia if, por ejemplo

 if df.order == key_df.order: # now check intervals...somehow 

pero esto no se aprovecha de la estructura del dataframe. Uno debe verificar por intervalo, es decir, algo como (df.start = key_df.end)

Estoy atascado. ¿Cuál es la forma más eficiente de hacer coincidir varias columnas en un “intervalo” en pandas? (La creación de una nueva columna si se cumple esta condición es sencilla)

Puede usar la merge con la boolean indexing , pero si los DataFrames son grandes, la escala es problemática:

 df1 = pd.merge(df, key_df, on='order', how='outer', suffixes=('','_key')) df1 = df1[(df1.start <= df1.start_key) & (df1.end <= df1.end_key)] print (df1) order start end value start_key end_key value_key 3 1 1342 1357 category1 1345.0 1392.0 category29 4 1 1342 1357 category1 1371.0 1383.0 category31 5 1 1342 1357 category1 1471.0 1501.0 category31 11 1 1459 1489 category7 1471.0 1501.0 category31 

EDITAR por comentario:

 df1 = pd.merge(df, key_df, on='order', how='outer', suffixes=('','_key')) df1 = df1[(df1.start <= df1.start_key) & (df1.end <= df1.end_key)] df1 = pd.merge(df, df1, on=['order','start','end', 'value'], how='left') print (df1) order start end value start_key end_key value_key 0 1 1342 1357 category1 1345.0 1392.0 category29 1 1 1342 1357 category1 1371.0 1383.0 category31 2 1 1342 1357 category1 1471.0 1501.0 category31 3 1 1459 1489 category7 1471.0 1501.0 category31 4 1 1572 1601 category23 NaN NaN NaN 5 1 1587 1599 category2 NaN NaN NaN 6 1 1591 1639 category1 NaN NaN NaN 7 15 792 813 category13 NaN NaN NaN 8 15 892 913 category5 NaN NaN NaN