需求和供给 Python 算法

Need and Supply Python Algorithm

我正在处理一个从 SQL 到 Python 的分配项目,因为我认为这将是 Python 的最佳处理方式。所以我下面有 2 tables。第一个 NEED TABLE 是我为每个合作伙伴、每个商店提供所需物品的地方,我根据他们需要的数量对它们进行排名, 的目标是首先为最需要的商店提供服务。 第二个 table 是我有可用供应数量的地方。

第三个输出 table 是我对 python 代码的目标输出。我如何在 python 上为此编写一个 while 代码循环以获得输出 table? (考虑到有数以千计的合作伙伴 ID 和 ITEM_ID)。我在考虑 while 语法,但如果您有其他建议,请随意!

NEED_TBL

PARTNER_ID ITEM_ID STORE NEED NEED_RANK
1 ID32 621 57 1
1 ID32 321 9 2
1 ID32 315 3 3
1 ID32 732 1 4
2 ID32 443 5 1
2 ID32 321 2 2

SUPPLY_TBL

PARTNER_ID ITEM_ID SUPPLY
1 ID32 57
2 ID32 6

输出TABLE

PARTNER_ID ITEM_ID STORE NEED NEED_RANK RECEIVED_SUPPLY
1 ID32 621 57 1 57
1 ID32 321 9 2 0
1 ID32 315 3 3 0
1 ID32 732 1 4 0
2 ID32 443 5 1 5
2 ID32 321 2 2 1

您可以使用 pandas 这样做:

import pandas as pd
import sqlite3
conn = sqlite3.connect('your_database.db')
df1 = pd.read_sql('SELECT * FROM table1', conn)
df2 = pd.read_sql('SELECT * FROM table2', conn)

df_final = df1.merge(df2, on = ["PARTNER_ID", "ITEM_ID"], how="left")
  1. merge 数据帧
  2. groupbycumsum 以获得每个 PARTNER_ID 和 ITEM_ID.
  3. 所需的总数量
  4. 计算供应数量,使用clip限制负值。
merged = need_tbl.merge(supply_tbl, on=["PARTNER_ID", "ITEM_ID"], how="left")
total_need = merged.groupby(["PARTNER_ID", "ITEM_ID"])["NEED"].transform("cumsum")
merged["RECEIVED_SUPPLY"] = (merged["NEED"]-(total_need-merged["SUPPLY"]).clip(0)).clip(0)
merged = merged.drop("SUPPLY", axis=1)

>>> merged

   PARTNER_ID ITEM_ID  STORE  NEED  NEED_RANK  RECEIVED_SUPPLY
0           1    ID32    621    57          1               57
1           1    ID32    321     9          2                0
2           1    ID32    315     3          3                0
3           1    ID32    732     1          4                0
4           2    ID32    443     5          1                5
5           2    ID32    321     2          2                1

我知道你要求 Python 代码,但如果我能说服你使用 SQL,这里是使用 window function

的尝试
with cte as
(select n.*,
        s.supply,
        sum(n.need) over (partition by n.partner_id, n.item_id order by n.need_rank) as cumulative_need
from need n
join supply s on n.partner_id=s.partner_id and s.item_id=n.item_id)

select partner_id,
       item_id,
       store,
       need,
       need_rank,
       case when supply-cumulative_need >=0 then need
            when need+supply-cumulative_need > 0 then need+supply-cumulative_need 
            else 0 
       end as received_supply
from cte      
order by partner_id, item_id, need_rank asc;