python & pandas- Cálculo entre dieciséis filas basadas en ciertos valores en columnas de DataFrame

Tengo un DataFrame grande (llamado df_NoMissing) con miles de filas, y necesito hacer cálculos y análisis con ellos.

NoDemande NoUsager Sens IdVehiculeUtilise Fait HeureArriveeSurSite HeureEffective Periods 0 42196000013 000001 + 287Véh 1 11/07/2015 08:02:07 11/07/2015 08:02:13 Matin 1 42196000013 000001 - 287Véh 1 11/07/2015 08:17:09 11/07/2015 08:17:13 Matin 2 42196000002 000314 + 263Véh 1 11/07/2015 09:37:43 11/07/2015 09:53:37 Matin 3 42196000016 002372 + 287Véh 1 11/07/2015 09:46:42 11/07/2015 10:01:39 Matin 4 42196000015 000466 + 287Véh 1 11/07/2015 09:46:42 11/07/2015 10:01:39 Matin 5 42196000002 000314 - 263Véh 1 11/07/2015 10:25:17 11/07/2015 10:38:11 Matin 6 42196000015 000466 - 287Véh 1 11/07/2015 10:48:51 11/07/2015 10:51:30 Matin 7 42196000016 002372 - 287Véh 1 11/07/2015 11:40:56 11/07/2015 11:41:01 Matin 8 42196000004 002641 + 263Véh 1 11/07/2015 13:39:29 11/07/2015 13:52:50 Soir 9 42196000004 002641 - 263Véh 1 11/07/2015 13:59:56 11/07/2015 14:07:41 Soir 

Lo que quiero hacer es tener dos filas con el mismo valor en la columna NoDemande , NoUsager , Periods , pero diferente en la columna Sens haga la resta entre la columna HeureArriveeSurSite y HeureEffective . Y como el resultado no corresponde con el DataFrame actual, el resultado se guardará en un nuevo DataFrame


Intenté separar el DataFrame identificando Sens para poder realizar la resta directamente. Pero no funciona en absoluto.

 df_new = pd.DataFrame(columns=['NoDemande', 'NoUsager', 'Periods', 'DureeTrajet'] df1 = df_NoMissing[(df_NoMissing['Sens'] == '+') & (df_NoMissing['Periods'] == 'Matin')] df2 = df_NoMissing[(df_NoMissing['Sens'] == '-') & (df_NoMissing['Periods'] == 'Matin')] df_new['DureeTrajet'] = df2['HeureArriveeSurSite'].values-df1['HeureEffective'].values 

Éste devolvió: ValueError: operands could not be broadcast together with shapes (1478,) (1479,)

También probé el modo cargado diciendo exactamente lo que quiero cada vez:

 df1.loc[df1['NoDemande'] == '42196000015','HeureEffective'] - df2.loc[df2['NoDemande'] == '42196000015','HeureArriveeSurSite'] 

Pero este volvió con:

 4 NaT 6 NaT dtype: timedelta64[ns] 

Entonces, ¿qué debo hacer para obtener lo que quiero?


EDITAR

La salida se verá como:

  NoDemande NoUsager Periods DureeTrajet 0 42196000013 000001 Matin 00:14:54 1 42196000002 000314 Matin 00:31:40 2 42196000016 002372 Matin 00:39:23 3 42196000015 000466 Matin 00:47:12 4 42196000004 002641 Soir 00:07:06 

Cualquier ayuda será realmente apreciada ~

De acuerdo, comenzando con su DF como se indica, creemos un índice en las columnas de agrupación y giremos a columnas para la acción Sens :

 temp = df.set_index(['NoDemande', 'NoUsager', 'Periods']).pivot(columns='Sens') 

Luego, tomamos la diferencia apropiada (según su código):

 duration = (temp['HeureArriveeSurSite', '-'] - temp['HeureEffective', '+']).to_frame(name='DureeTrajet').reset_index() 

Eso te da entonces:

  NoDemande NoUsager Periods DureeTrajet 0 42196000002 314 Matin 00:31:40 1 42196000004 2641 Soir 00:07:06 2 42196000013 1 Matin 00:14:56 3 42196000015 466 Matin 00:47:12 4 42196000016 2372 Matin 01:39:17 

Así que mi solución es:

  1. para unir df1 y df2 (no los agregue, sino que se unan con la unión externa). Para esto, debe cambiar el nombre de todas las columnas en df2 excepto de NoDemande, NoUsager y Period. por ejemplo, en df1 será Sens, en df2 – Sens2. Y luego de unirte intenta restar las fechas que quieras.

  2. También puede ser que obtenga algunas faltas, si alguna de las entradas no tiene un par con otro valor de Sens. La manguera que no lo son, solo deberías filtrar, creo. Porque solo necesita DureeTrajet para aquellos usuarios que tuvieron varias sesiones, ¿no es así? Entonces, si un usuario tuvo solo una sesión, ¿no lo necesita en la tabla df_new?

  3. Al final deberías tener solo esas entradas, que tienen pares. Y para esto puedes restar las fechas.

EDITAR:

Si algunas entradas no solo tienen un par, sino dos o más pares, debe definir qué par tiene más prioridad / tiene más sentido.