Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

163
Views
For loop que suma y resta de columnas pandas

Entonces tengo este df

 SUPPLIER PRODUCTID STOREID BALANCE AVG_SALES TO_SHIP SUP1 P1 STR1 50 5 18 SUP1 P1 STR2 6 7 18 SUP1 P1 STR3 74 4 18 SUP2 P4 STR1 35 3 500 SUP2 P4 STR2 5 4 500 SUP2 P4 STR3 54 7 500

Siempre está agrupado por ID de proveedor y producto. La columna TO_SHIP es única para el grupo. Entonces, por ejemplo, tengo 18 productos para ese SUP1 con P1 para enviar. Luego agrego nuevas columnas:

  • Calcular Wk_bal = (BALANCE / AVG_SALES)
  • Clasificación Wk_bal por grupo de ID de producto-proveedor
  • Wk_bal más bajo para el grupo: SEND_PKGS = +1
  • Luego, calcule Wk_bal nuevamente pero agregue el paquete enviado = ((BALANCE+SEND_PKGS) / AVG_SALES)
  • Así que esto se repite hasta que todo TO_SHIP se haya distribuido a las tiendas que más lo necesitan.

Para visualizar una carrera:

Primera salida (calcule wk_bal, luego envíe 1 paquete al más bajo):

 SUPPLIER PRODUCTID STOREID BALANCE AVG_SALES TO_SHIP Wk_Bal SEND_PKGS SUP1 P1 STR1 50 5 18 10 0 SUP1 P1 STR2 6 4 18 1.5 1 SUP1 P1 STR3 8 4 18 2 0 SUP2 P4 STR1 35 3 500 11.67 0 SUP2 P4 STR2 5 4 500 1.25 1 SUP2 P4 STR3 54 7 500 7.71 0

Segunda salida (calcular wk_bal actualizado, enviar un paquete al más bajo):

 SUPPLIER PRODUCTID STOREID BALANCE AVG_SALES TO_SHIP Wk_Bal SEND_PKGS SUP1 P1 STR1 50 5 17 10 0 SUP1 P1 STR2 8 4 17 1.75 2 SUP1 P1 STR3 8 4 17 2 0 SUP2 P4 STR1 35 3 499 11.67 0 SUP2 P4 STR2 7 4 499 1.5 2 SUP2 P4 STR3 54 7 499 7.71 0

Y así sucesivamente... hasta que quede_envío, calcule-clasifique-entregue un paquete. El motivo de este proceso es que quiero asegurarme de que la tienda con el wk_balance más bajo obtenga el paquete primero. (y hay muchas otras razones por las que)

Inicialmente construí esto en SQL, pero con la complejidad me mudé a python. Desafortunadamente, mi Python no es muy bueno para generar bucles con varias condiciones, especialmente en pandas df. Hasta ahora lo he intentado (y he fallado):

 df['Wk_Bal'] = 0 df['TO_SHIP'] = 0 for i in df.groupby(["SUPPLIER", "PRODUCTID"])['TO_SHIP']: if i > 0: df['Wk_Bal'] = df['BALANCE'] / df['AVG_SALES'] df['TO_SHIP'] = df.groupby(["SUPPLIER", "PRODUCTID"])['TO_SHIP']-1 df['SEND_PKGS'] = + 1 df['BALANCE'] = + 1 else: df['TO_SHIP'] = 0

¿Cómo hago esto mejor?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Espero haber entendido todos sus requisitos. Aquí están sus datos originales:

 df = pd.DataFrame({'SUPPLIER': ['SUP1', 'SUP1', 'SUP1', 'SUP2', 'SUP2', 'SUP2'], 'PRODUCTID': ['P1', 'P1', 'P1', 'P4', 'P4', 'P4'], 'STOREID': ['STR1', 'STR2', 'STR3', 'STR1', 'STR2', 'STR3'], 'BALANCE': [50, 6, 74, 35, 5, 54], 'AVG_SALES': [5, 4, 4, 3, 4, 7], 'TO_SHIP': [18, 18, 18, 500, 500, 500]})

Aquí está mi enfoque:

 df['SEND_PKGS'] = 0 df['Wk_bal'] = df['BALANCE'] / df['AVG_SALES'] while (df['TO_SHIP'] != 0).any(): lowest_idx = df[df['TO_SHIP'] > 0].groupby(["SUPPLIER", "PRODUCTID"])['Wk_bal'].idxmin() df.loc[lowest_idx, 'SEND_PKGS'] += 1 df['Wk_bal'] = (df['BALANCE'] + df['SEND_PKGS']) / df['AVG_SALES'] df.loc[df['TO_SHIP'] > 0, 'TO_SHIP'] -= 1

Sigo actualizando df hasta que la columna TO_SHIP es todo cero. Luego incremento SEND_PKGS que corresponden al Wk_bal más bajo de cada grupo. Luego actualice Wk_bal y reduzca las columnas TO_SHIP que no sean cero.

termino con:

 SUPPLIER PRODUCTID STOREID BALANCE AVG_SALES TO_SHIP SEND_PKGS Wk_bal 0 SUP1 P1 STR1 50 5 0 0 10.000000 1 SUP1 P1 STR2 6 4 0 18 6.000000 2 SUP1 P1 STR3 74 4 0 0 18.500000 3 SUP2 P4 STR1 35 3 0 92 42.333333 4 SUP2 P4 STR2 5 4 0 165 42.500000 5 SUP2 P4 STR3 54 7 0 243 42.428571

Editar: en el caso de múltiples mínimos de Wk_bal , podemos elegir en función del mínimo AVG_SALES :

 def find_min(x): num_mins = x["Wk_bal"].loc[x["Wk_bal"] == x["Wk_bal"].min()].shape[0] if num_mins == 1: return(x["Wk_bal"].idxmin()) else: min_df = x.loc[x["Wk_bal"] == x["Wk_bal"].min()] return(min_df["AVG_SALES"].idxmin())

Entonces, más o menos como antes:

 df['SEND_PKGS'] = 0 df['Wk_bal'] = df['BALANCE'] / df['AVG_SALES'] while (df['TO_SHIP'] != 0).any(): lowest_idx = df[df['TO_SHIP'] > 0].groupby(["SUPPLIER", "PRODUCTID"])[['Wk_bal', 'AVG_SALES']].apply(find_min) df.loc[lowest_idx, 'SEND_PKGS'] += 1 df['Wk_bal'] = (df['BALANCE'] + df['SEND_PKGS']) / df['AVG_SALES'] df.loc[df['TO_SHIP'] > 0, 'TO_SHIP'] -= 1
over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!