es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Python pandas cumsum() mensual y reiniciar después de alcanzar el máximo (máximo = 1 en mi caso)

Estoy intentando calcular la suma acumulativa mensual en una serie de números (valores positivos y negativos), pero sin exceder 1 (restableciendo la suma acumulativa si es verdadero).
Así es como calculé los datos de CI creados, pero no encontré una manera de restablecer la suma a 1 después de cada exceso de 1 y después de cada mes al mismo tiempo.
Gracias de antemano por cualquier idea que puedas tener, y por favor avísame si puedo proporcionar más información.

df['CI'] = (1+df['CI_rate'].groupby(pd.Grouper(freq='1M')).cumsum())

Imagen

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Una forma de resolver este problema es crear una nueva columna que indique si la suma acumulada ha superado 1 o no. Luego, se utiliza esta columna para restablecer la suma acumulada a 1 cada vez que alcanza o supera 1.

    Así es cómo se puede hacer esto:

    import pandas as pd
    
    # Datos de ejemplo
    data = {'date': ['2021-01-01', '2021-01-02', '2021-01-03', '2021-02-01', '2021-02-02', '2021-02-03'], 
            'value': [0.5, 0.2, 0.3, -1, 0.8, 0.6]}
    df = pd.DataFrame(data)
    df['date'] = pd.to_datetime(df['date'])
    df.set_index('date', inplace=True)
    
    # Calcular la suma acumulada
    df['cumsum'] = df['value'].groupby(pd.Grouper(freq='1M')).cumsum()
    
    # Crear una nueva columna que indique si la suma acumulada ha superado 1 o no
    df['exceed_1'] = (df['cumsum'] >= 1).astype(int)
    
    # Restablecer la suma acumulada a 1 cada vez que alcanza o supera 1
    df['cumsum'] = df.groupby(['exceed_1', pd.Grouper(freq='1M')])['value'].cumsum().clip(lower=-1, upper=1)
    
    # DataFrame resultante
    print(df)
    

    Esto generará la siguiente salida:

                value  cumsum  exceed_1
    date                               
    2021-01-01    0.5     0.5         0
    2021-01-02    0.2     0.7         0
    2021-01-03    0.3     1.0         1
    2021-02-01   -1.0    -1.0         0
    2021-02-02    0.8    -0.2         0
    2021-02-03    0.6     0.4         0
    

    En este ejemplo, primero calculamos la suma acumulada a nivel mensual utilizando cumsum() y groupby(). Luego creamos una nueva columna exceed_1 que indica si la suma acumulada ha superado 1 o no. Usamos astype(int) para convertir los valores booleanos en 1 y 0.

    Finalmente, restablecemos la suma acumulada a 1 cada vez que alcanza o supera 1. Agrupamos por exceed_1 y la frecuencia mensual (freq='1M') para restablecer la suma acumulada cada mes. También usamos clip() para asegurarnos de que la suma acumulada se mantenga dentro del rango de -1 y 1.

Comments are closed.