需求和供给 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")
merge
数据帧
groupby
和 cumsum
以获得每个 PARTNER_ID 和 ITEM_ID. 所需的总数量
- 计算供应数量,使用
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;
我正在处理一个从 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")
merge
数据帧groupby
和cumsum
以获得每个 PARTNER_ID 和 ITEM_ID. 所需的总数量
- 计算供应数量,使用
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;