tutorial seleccionar recorrer leer hacer español documentacion datos data con columnas python pandas datetime dataframe intervals

python - seleccionar - recorrer data frame pandas



¿Cómo unir dos marcos de datos para los que los valores de columna están dentro de un cierto rango? (5)

Dados dos marcos de datos df_1 y df_2 , cómo unirlos de modo que la columna de fecha y hora df_1 encuentre entre el start y el end marco de datos df_2 :

print df_1 timestamp A B 0 2016-05-14 10:54:33 0.020228 0.026572 1 2016-05-14 10:54:34 0.057780 0.175499 2 2016-05-14 10:54:35 0.098808 0.620986 3 2016-05-14 10:54:36 0.158789 1.014819 4 2016-05-14 10:54:39 0.038129 2.384590 print df_2 start end event 0 2016-05-14 10:54:31 2016-05-14 10:54:33 E1 1 2016-05-14 10:54:34 2016-05-14 10:54:37 E2 2 2016-05-14 10:54:38 2016-05-14 10:54:42 E3

Obtenga el event correspondiente donde df1.timestamp está entre df_2.start y df2.end

timestamp A B event 0 2016-05-14 10:54:33 0.020228 0.026572 E1 1 2016-05-14 10:54:34 0.057780 0.175499 E2 2 2016-05-14 10:54:35 0.098808 0.620986 E2 3 2016-05-14 10:54:36 0.158789 1.014819 E2 4 2016-05-14 10:54:39 0.038129 2.384590 E3


En este método, asumimos que se usan objetos TimeStamp.

df2 start end event 0 2016-05-14 10:54:31 2016-05-14 10:54:33 E1 1 2016-05-14 10:54:34 2016-05-14 10:54:37 E2 2 2016-05-14 10:54:38 2016-05-14 10:54:42 E3 event_num = len(df2.event) def get_event(t): event_idx = ((t >= df2.start) & (t <= df2.end)).dot(np.arange(event_num)) return df2.event[event_idx] df1["event"] = df1.timestamp.transform(get_event)

Explicación de get_event

Para cada marca de tiempo en df1 , diga t0 = 2016-05-14 10:54:33 ,

(t0 >= df2.start) & (t0 <= df2.end) contendrá 1 verdadero. (Ver ejemplo 1). Luego, tome un producto punto con np.arange(event_num) para obtener el índice del evento al que pertenece t0 .

Ejemplos:

Ejemplo 1

t0 >= df2.start t0 <= df2.end After & np.arange(3) 0 True True -> T 0 event_idx 1 False True -> F 1 -> 0 2 False True -> F 2

Tome t2 = 2016-05-14 10:54:35 para otro ejemplo

t2 >= df2.start t2 <= df2.end After & np.arange(3) 0 True False -> F 0 event_idx 1 True True -> T 1 -> 1 2 False True -> F 2

Finalmente usamos transform para transformar cada marca de tiempo en un evento.


Opción 1

idx = pd.IntervalIndex.from_arrays(df_2[''start''], df_2[''end''], closed=''both'') df_2.index=idx df_1[''event'']=df_2.loc[df_1.timestamp,''event''].values

opcion 2

df_2[''timestamp'']=df_2[''end''] pd.merge_asof(df_1,df_2[[''timestamp'',''event'']],on=''timestamp'',direction =''forward'',allow_exact_matches =True) Out[405]: timestamp A B event 0 2016-05-14 10:54:33 0.020228 0.026572 E1 1 2016-05-14 10:54:34 0.057780 0.175499 E2 2 2016-05-14 10:54:35 0.098808 0.620986 E2 3 2016-05-14 10:54:36 0.158789 1.014819 E2 4 2016-05-14 10:54:39 0.038129 2.384590 E3


Puedes usar el módulo pandasql

import pandasql as ps sqlcode = '''''' select df_1.timestamp ,df_1.A ,df_1.B ,df_2.event from df_1 inner join df_2 on d1.timestamp between df_2.start and df2.end '''''' newdf = ps.sqldf(sqlcode,locals())


Una solución simple es crear un interval index desde el start and end configuración closed = both luego usar get_loc para obtener el evento, es decir (Espero que todas las horas estén en dtype de fecha y hora)

df_2.index = pd.IntervalIndex.from_arrays(df_2[''start''],df_2[''end''],closed=''both'') df_1[''event''] = df_1[''timestamp''].apply(lambda x : df_2.iloc[df_2.index.get_loc(x)][''event''])

Salida:

timestamp A B event 0 2016-05-14 10:54:33 0.020228 0.026572 E1 1 2016-05-14 10:54:34 0.057780 0.175499 E2 2 2016-05-14 10:54:35 0.098808 0.620986 E2 3 2016-05-14 10:54:36 0.158789 1.014819 E2 4 2016-05-14 10:54:39 0.038129 2.384590 E3


idx = pd.IntervalIndex.from_arrays(df_2[''start''], df_2[''end''], closed=''both'') event = df_2.loc[idx.get_indexer(df_1.timestamp), ''event''] event 0 E1 1 E2 1 E2 1 E2 2 E3 Name: event, dtype: object df_1[''event''] = event.values df_1 timestamp A B event 0 2016-05-14 10:54:33 0.020228 0.026572 E1 1 2016-05-14 10:54:34 0.057780 0.175499 E2 2 2016-05-14 10:54:35 0.098808 0.620986 E2 3 2016-05-14 10:54:36 0.158789 1.014819 E2 4 2016-05-14 10:54:39 0.038129 2.384590 E3

Referencia: una pregunta sobre IntervalIndex.get_indexer.