¿Existe alguna manera de vectorizar el siguiente código de Python (pandas) para aumentar la velocidad?
Tengo 2 DataFrames
A_df = pd.DataFrame(data = np.arange(2, 103, 10) + np.random.randn(11),
columns = ['Tiempo(s)'])
B_df = pd.DataFrame(data = zip(range(1, 102), np.random.randn(101)),
columns = ['Tiempo(s)', 'Valor'])
A_df.head()
Tiempo(s)
0 2.751352
1 12.028663
2 20.638388
3 29.821199
4 42.516302
B_df.head()
Tiempo(s) Valor
0 1 1.075801
1 2 0.890754
2 3 -0.015543
3 4 0.085298
4 5 0.208645
Quiero agregar una nueva columna Valor de B en T
a A_df
, que es el valor más reciente de B (de B_df
) en el tiempo t (en A_df
).
Actualmente estoy haciendo esto utilizando el método apply()
de la siguiente manera:
A_df['Valor de B en T'] = A_df.apply(lambda x: B_df.loc[B_df['Tiempo(s)'] <= x['Tiempo(s)'], 'Valor'].values[-1], axis = 1)
A_df
Tiempo(s) Valor de B en T
0 2.751352 -0.891782
1 12.028663 2.416335
2 20.638388 -0.186364
3 29.821199 -0.148716
4 42.516302 0.821272
Me preguntaba si hay alguna manera de vectorizar la funcionalidad que se lleva a cabo utilizando el método apply()
para acelerar el código.
davy.ai
Sí, hay una forma de vectorizar la funcionalidad utilizando la función
merge_asof()
de pandas. Esta función puede realizar una fusión “as-of” que se puede utilizar para hacer coincidir según la clave más cercana en lugar de las claves iguales. Aquí está cómo se puede usar en este escenario:Este código fusionará los dos dataframes en la columna ‘Time(s)’, haciendo coincidir la clave más cercana, y luego cambiará el nombre de la columna ‘Value’ a ‘Value of B at T’. Eliminará cualquier valor duplicado y solo conservará el último valor para cada tiempo en A_df. Finalmente, restablecerá el índice para que el dataframe resultante esté ordenado por ‘Time(s)’.
El dataframe resultante
merged_df
tendrá las mismas columnas queA_df
más la nueva columna ‘Value of B at T’ con el valor más reciente de B en cada tiempo de A_df.