El dataframe de Pandas se aplica a la fila anterior para calcular la diferencia

Tengo el siguiente dataframe de pandas que contiene 2 columnas (simplificado). La primera columna contiene los nombres de los jugadores y la segunda columna contiene fechas (objetos de datetime y datetime ):

  player date A 2010-01-01 A 2010-01-09 A 2010-01-11 A 2010-01-15 B 2010-02-01 B 2010-02-10 B 2010-02-21 B 2010-02-23 

Quiero agregar una columna diff que representa la diferencia de tiempo en días por jugador . El resultado debería verse así:

  player date diff A 2010-01-01 0 A 2010-01-09 8 A 2010-01-11 2 A 2010-01-15 4 B 2010-02-01 0 B 2010-02-10 9 B 2010-02-21 11 B 2010-02-23 2 

La primera fila tiene 0 para diff, porque no hay una fecha anterior. La segunda fila muestra 8 , porque la diferencia entre 2010-01-01 y 2010-01-09 es de ocho días.

El problema no es calcular la diferencia entre dos objetos de datetime . Simplemente no estoy seguro de cómo agregar la nueva columna. Sé que primero tengo que crear un groupby ( df.groupby('player') ) y luego usar apply (o tal vez transform ). Sin embargo, estoy atascado, porque para calcular la diferencia, necesito referirme a la fila anterior en la función de aplicación, y no sé cómo hacerlo, si es posible.

Muchas gracias.

ACTUALIZACIÓN: Después de probar las dos soluciones propuestas a continuación, descubrí que no funcionaban con mi código. Después de mucho dolor de cabeza, descubrí que mis datos tenían índices duplicados. Entonces, después de descubrir que tengo índices duplicados, un simple df.reset_index() resolvió mi problema y las soluciones propuestas funcionaron. Como ambas soluciones funcionan, pero solo puedo marcar una como correcta, elegiré la solución más concisa / corta. Gracias a los dos, sin embargo!

Usted puede simplemente escribir:

 df['difference'] = df.groupby('player')['date'].diff().fillna(0) 

Esto le da a la nueva columna timedelta con los valores correctos:

  player date difference 0 A 2010-01-01 0 days 1 A 2010-01-09 8 days 2 A 2010-01-11 2 days 3 A 2010-01-15 4 days 4 B 2010-02-01 0 days 5 B 2010-02-10 9 days 6 B 2010-02-21 11 days 7 B 2010-02-23 2 days 

(He usado el nombre “diferencia” en lugar de “dif” para distinguir el nombre del método diff .)

Otra forma si desea implementarlo manualmente es hacer lo siguiente

 def date_diff(df): df['difference'] = df['date'] - df['date'].shift() df['difference'].fillna(0 ,inplace = True) return df In [30]: df_final = df.groupby(df['player']).apply(date_diff) df_final Out[30]: player date difference A 2010-01-01 0 days A 2010-01-09 8 days A 2010-01-11 2 days A 2010-01-15 4 days B 2010-02-01 0 days B 2010-02-10 9 days B 2010-02-21 11 days B 2010-02-23 2 days 

shift() es una buena función, sin embargo, si necesita evitar la duplicación de datos , sugeriría el siguiente método.

 def date_diff(row): index = df.index.get_loc(row.name) if index == 0: return np.nan prev_row = df.iloc[index - 1] return row['date'] - prev_row['date'] df['difference'] = df.apply(date_diff, axis=1)