python数据框架中最便宜的项目组合
我有一个python的csv文件python数据框架中最便宜的项目组合,python,pandas,Python,Pandas,我有一个python的csv文件 SHOP_ID, COST, ITEM 1, 2.00, A 1, 1.25, B 1, 2.00, C 1, 1.00, D 1, 1.00, "A, B" 1, 1.50, "A, C" 1, 2.50, "A, D" 2, 3.00, A 2, 1.00, B 2, 1.20, C 2, 1.25, D 我在python中将此文件作为数据帧读取 现在,假设我输入A、B、C、D作为输入,并希望从我的数据框中为该用户输入找到最便宜的项目组合,那么我应该得到:
SHOP_ID, COST, ITEM
1, 2.00, A
1, 1.25, B
1, 2.00, C
1, 1.00, D
1, 1.00, "A, B"
1, 1.50, "A, C"
1, 2.50, "A, D"
2, 3.00, A
2, 1.00, B
2, 1.20, C
2, 1.25, D
我在python中将此文件作为数据帧读取
现在,假设我输入A、B、C、D作为输入,并希望从我的数据框中为该用户输入找到最便宜的项目组合,那么我应该得到:-
SHOP_ID=1
A,B(1.00)+A,C(1.50)+D(1.00) = 3.50
用户将获得A、A、B、C、D,即额外的A,但只要总成本最低,我们不关心用户是否获得额外的免费物品
我不知道如何着手解决这个问题。非常感谢您的帮助。以下是一种方法:
def build_shops(shop_text):
shops = {}
for item_info in shop_text:
shop_id,cost,items = item_info.replace(' ', '').split(',')
cost = float(cost)
items = items.split('+')
if shop_id not in shops:
shops[shop_id] = {}
shop_dict = shops[shop_id]
for item in items:
if item not in shop_dict:
shop_dict[item] = []
shop_dict[item].append([cost,items])
return shops
def solve_one_shop(shop, items):
if len(items) == 0:
return [0.0, []]
for item in items:
if item not in shop:
return [float('inf'), []]
all_possible = []
first_item = items[0]
for (price,combo) in shop[first_item]:
sub_set = [x for x in items if x not in combo]
price_sub_set,solution = solve_one_shop(shop, sub_set)
solution.append([price,combo])
all_possible.append([price+price_sub_set, solution])
cheapest = min(all_possible, key=(lambda x: x[0]))
return cheapest
def solver(input_data, required_items):
shops = build_shops(input_data)
result_all_shops = []
for shop_id,shop_info in shops.iteritems():
(price, solution) = solve_one_shop(shop_info, required_items)
if price != float('inf'):
result_all_shops.append([shop_id, price, solution])
if len(result_all_shops) == 0:
print('No shop has all required items')
return
shop_id,total_price,solution = min(result_all_shops, key=(lambda x: x[1]))
print('SHOP_ID=%s' % shop_id)
sln_str = [','.join(items)+'(%0.2f)'%price for (price,items) in solution]
sln_str = '+'.join(sln_str)
print(sln_str + ' = %0.2f' % total_price)
测试:
输出:
SHOP_ID=1
D(1.00)+A,C(1.50)+A,B(1.00) = 3.50
请注意,我使用:
1, 1.00, A+B
而不是
1, 1.00, "A, B"
作为输入格式,只是为了便于格式化。您可以根据自己的格式修改函数“build_shops”
这个解决方案基本上是这样做的:选择项目‘A’,然后计算集合‘B’、‘C’、‘D’的解决方案。要计算解('B','C','D'),它选择'B'和计算集('C','D')。这是一种分而治之的方法()。关键代码是:
sub_set = [x for x in items if x not in combo]
price_sub_set,solution = solve_one_shop(shop, sub_set)
为了帮助理解代码,我将“build_shops”的输出粘贴到这里:
这个解决方案迭代所有可能的组合,这是蛮力。因此,如果数据集非常大,将不会非常有效
测试用例2:
input_data = [
'1, 2.00, burger',
'1, 1.25, tofu',
'1, 2.00, tuna',
'1, 1.00, salad',
'1, 1.00, burger+tofu',
'1, 1.50, burger+tuna',
'1, 2.50, burger+salad',
'2, 3.00, burger',
'2, 1.00, tofu',
'2, 1.20, tuna',
'2, 1.25, salad',
]
required_items = ['burger','tofu','tuna','salad']
solver(input_data, required_items)
产出2:
SHOP_ID=1
salad(1.00)+burger,tuna(1.50)+burger,tofu(1.00) = 3.50
谢谢zee,你能简要介绍一下代码逻辑吗?@sunita,我在答案中插入了一点解释。你可以在“这个解决方案基本上是这样做的……”中查看它。嗨,zee,你的代码不起作用。我明白了:SHOP_ID=1d(1.00)+A,C(1.50)+A,B(1.00)=1.00在spyder行中运行您的代码_NO:46“sln_str=[','。join(items)+'(%0.2f)'(price,items)in solution]“列表理解从第44行重新定义了价格。第44行“shop\u id,price,solution=min(result\u all\u shop,key=(lambda x:x[1])”@sunita,很抱歉出现了一个bug,正如您所看到的——变量被重新定义。我对答案做了一些修改(将“价格”改为“总价”)
input_data = [
'1, 2.00, burger',
'1, 1.25, tofu',
'1, 2.00, tuna',
'1, 1.00, salad',
'1, 1.00, burger+tofu',
'1, 1.50, burger+tuna',
'1, 2.50, burger+salad',
'2, 3.00, burger',
'2, 1.00, tofu',
'2, 1.20, tuna',
'2, 1.25, salad',
]
required_items = ['burger','tofu','tuna','salad']
solver(input_data, required_items)
SHOP_ID=1
salad(1.00)+burger,tuna(1.50)+burger,tofu(1.00) = 3.50