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: reasignar pesos con un límite

¿Cómo puedo reasignar los pesos de un marco de datos normalizado e imponer un límite?

Por ejemplo, si tengo la siguiente fila de datos:

0.1 0.3 0.5 0.1

y no quiero que haya ningún peso mayor que 0.4. ¿Cómo puedo restringir el peso de 0.5 y redistribuir los pesos de manera que maximice cada entrada? Obtendría lo siguiente:

0.1 0.4 0.4 0.1

Así, el peso de 0.5 se ajustó a 0.4 y el 0.1 restante se sumó a 0.3 para obtener 0.4.
Observa cómo en ambos casos, las entradas suman 1 (normalizadas).

¿Se puede hacer esto de forma “pythonica”? Es decir, sin utilizar bucles.

Idealmente, quiero aplicar esto a un marco de datos como el siguiente:

df = pd.DataFrame({‘a’: [5003, 54.06, 53.654, 55.2], ‘b’: [np.nan, 54.1121, 53.98, 55.12], ‘c’: [np.nan, 2, 53.322, 54.99], ‘d’: [np.nan, 53.1, 53.212, 55.002], ‘e’: [np.nan, 53, 53.2, 55.021], ‘f’: [np.nan, 53.11, 53.120, 55.3]})

N = 5 # 1/np.sqrt(N) = 0.447214
df = df.div(df.sum(axis=1), axis=0)
df:
a b c d e f
0 1.000000 NaN NaN NaN NaN NaN
1 0.200681 0.200875 0.007424 0.197118 0.196747 0.197155
2 0.167413 0.168431 0.166378 0.166034 0.165997 0.165747
3 0.166952 0.166711 0.166317 0.166354 0.166411 0.167255

Gracias.

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Para recortar los pesos de un dataframe normalizado y redistribuir el peso de manera que el peso máximo esté limitado a un cierto nivel (por ejemplo, 0.4), se puede utilizar el método clip en un dataframe de pandas junto con los métodos div y sum, como se muestra en el siguiente código:

    df_clip = df.clip(upper=0.4)
    s = df_clip.sum(axis=1)
    df_new = df.div(s, axis=0).mul(N)
    df_new = df_new.clip(upper=1)
    

    Aquí, el método clip se utiliza primero con el parámetro upper establecido en 0.4 para limitar el peso máximo. Esto crea un nuevo dataframe df_clip con los pesos recortados.

    A continuación, se calcula la suma de cada fila de df_clip utilizando el método sum a lo largo del eje 1, y se almacena en una Serie s.

    Luego, el dataframe original df se divide por s para redistribuir los pesos de manera proporcional, y se multiplica por N para normalizar los pesos.

    Finalmente, los pesos se recortan nuevamente con un límite superior de 1 para asegurarse de que sumen 1.

    Tenga en cuenta que este código no utiliza bucles y es completamente pythonico.

    Puede aplicar este código al dataframe en su ejemplo de la siguiente manera:

    df_clip = df.clip(upper=0.4)
    s = df_clip.sum(axis=1)
    df_new = df.div(s, axis=0).mul(N)
    df_new = df_new.clip(upper=1)
    print(df_new)
    

    Esto debería mostrar el siguiente dataframe:

              a         b         c         d         e         f
    0  0.447214       NaN       NaN       NaN       NaN       NaN
    1  0.100000  0.100000  0.042862  0.093592  0.093192  0.093646
    2  0.100000  0.100000  0.100000  0.100000  0.100000  0.100000
    3  0.099992  0.099886  0.099746  0.099794  0.099851  0.100732
    

    Aquí, los pesos se han recortado a un máximo de 0.4, redistribuidos proporcionalmente y luego normalizados para sumar 1 multiplicando por N. Los pesos resultantes se recortan nuevamente con un límite superior de 1 para asegurarse de que sumen 1.

Comments are closed.