Valores de referencia en la fila anterior con mapa o aplicar.

Dado un df dataframe, me gustaría generar una nueva variable / columna para cada fila en función de los valores de la fila anterior. df está ordenado para que el orden de las filas sea significativo.

Normalmente, podemos usar un map o apply , pero parece que ninguno de ellos permite el acceso a los valores en la fila anterior.

Por ejemplo, dado el abc las filas existentes, quiero generar una nueva columna d , que se basa en algún cálculo utilizando el valor de c en la fila anterior.

¿Cómo debo hacerlo en pandas?

Si solo desea hacer un cálculo basado en la fila anterior, puede calcular y luego cambiar:

 In [2]: df = pd.DataFrame({'a':[0,1,2], 'b':[0,10,20]}) In [3]: df Out[3]: ab 0 0 0 1 1 10 2 2 20 # a calculation based on other column In [4]: df['c'] = df['b'] + 1 # shift the column In [5]: df['c'] = df['c'].shift() In [6]: df Out[6]: abc 0 0 0 NaN 1 1 10 1 2 2 20 11 

Si desea realizar un cálculo basado en varias filas, puede consultar la función rolling_apply ( http://pandas.pydata.org/pandas-docs/stable/computation.html#moving-rolling-statistics-moments y http: //pandas.pydata.org/pandas-docs/stable/generated/pandas.rolling_apply.html#pandas.rolling_apply )

Puede usar la función ‘aplicar’ del dataframe y aprovechar el parámetro ‘kwargs’ no utilizado para almacenar la fila anterior.

 import pandas as pd df = pd.DataFrame({'a':[0,1,2], 'b':[0,10,20]}) new_col = 'c' def apply_func_decorator(func): prev_row = {} def wrapper(curr_row, **kwargs): val = func(curr_row, prev_row) prev_row.update(curr_row) prev_row[new_col] = val return val return wrapper @apply_func_decorator def running_total(curr_row, prev_row): return curr_row['a'] + curr_row['b'] + prev_row.get('c', 0) df[new_col] = df.apply(running_total, axis=1) print(df) # Output will be: # abc # 0 0 0 0 # 1 1 10 11 # 2 2 20 33 

Este ejemplo utiliza un decorador para almacenar la fila anterior en un diccionario y luego pasarla a la función cuando Pandas la llama en la siguiente fila.

Descargo de responsabilidad 1: la variable ‘prev_row’ comienza vacía para la primera fila, por lo que al usarla en la función de aplicación, tuve que proporcionar un valor predeterminado para evitar un ‘KeyError’.

Descargo de responsabilidad 2: Estoy bastante seguro de que esto será más lento en la operación de aplicación, pero no hice ninguna prueba para determinar cuánto.