我有一个数据框,其中包含订单order_items
及其总价格order_price
的列表。
order_type
列包含订单类型:早餐,午餐或晚餐。
我的目标是确认给定的总数order_price
是正确的。通过将数量(元组中的第二个项目)乘以项目价格。然后将一个订单的所有价格相加,并将其存储在新列order_price_checked
中。
我的数据集样本:
order_id order_items order_type order_price
0 ORDB10489 [('Coffee', 4), ('Salad', 10), ('Chicken', 8), ('Steak', 10)] Lunch 1002.00
1 ORDZ00319 [('Fish&Chips', 9), ('Pasta', 5), ('Shrimp', 3)] Dinner 614.50
2 ORDB00980 [('Pasta', 6), ('Fish&Chips', 10)] Dinner 515.00
3 ORDY10003 [('Chicken', 7), ('Steak', 1)] Lunch 269.00
4 ORDK04121 [('Steak', 9), ('Chicken', 5)] Lunch 565.00
5 ORDC10404 [('Burger', 3), ('Salad', 6), ('Fries', 7)] Lunch 280.20
6 ORDK05183 [('Chicken', 1), ('Steak', 10), ('Fries', 4), ('Salad', 6)] Lunch 633.20
我将每个order_type
的价格存储在单独的字典中。
例如,lunchDict
用于午餐订单。
{'Burger': 31.0, 'Fries': 12.0, 'Chicken': 32.0, 'Salad': 17.2, 'Steak': 45.0}
我的方法是将元组中的第一项与字典键匹配。如果它与键匹配,那么我将元组(数量)中的第二项乘以相应键(价格)的值。
然后获得所有订单的总数并将其添加到新列order_price_checked
中。
所需的输出(我仅显示两列以节省空间): 例如索引1和4表示我们的价格有误。
order_price order_price_checked
0 1002.00 1002.00
1 614.50 600.20
2 515.00 515.00
3 269.00 269.00
4 565.00 500.00
5 280.20 280.20
6 633.20 633.20
我试图在for loop
中做到这一点:
for item in dirtyData['order_items']:
for mytuple in item:
if mytuple[0] in breakfastDict:
tot=mytuple[1]*breakfastDict[mytuple[0]]
print(tot)
但这不是一个明确的方法,我无法确定我正在处理哪一行。 任何输入都会有所帮助。谢谢
答案 0 :(得分:1)
您可以在每行上使用.apply
和自定义函数来求和。
示例数据集(不能pd.read_clipboard
属于您,因为它有空格;这就是为什么最好举一个带有代码的示例来创建日期集的原因)
将熊猫作为pd导入
df = pd.DataFrame(columns = ['order_id','order_items','order_type', 'order_price'],
data=[
('ORDB10489', [('Coffee', 4), ('Salad', 10), ('Chicken', 8), ('Steak', 10)], 'Lunch', 1002.00),
('ORDZ00319', [('Fish&Chips', 9), ('Pasta', 5), ('Shrimp', 3)], 'Dinner', 614.50)
])
设置价格字典,以及用于在膳食类型及其各自的价格指标之间进行映射的字典:
dinner_dict = {'Shrimp': 100, 'Pasta': 60, 'Fish&Chips': 14.5/9}
lunch_dict = {'Coffee': 33, 'Salad': 33, 'Chicken': 33, 'Steak': 10000}
meal_dict = {'Dinner': dinner_dict, 'Lunch': lunch_dict}
定义自定义函数(您也可以使用内联lambda
来实现,但这种方式更清晰):
def sum_items_in_order(order, meal_dict):
return sum(item[1]*meal_dict[order['order_type']][item[0]] for item in order['order_items'])
您的结果将符合要求:
df.apply(lambda order: sum_items_in_order(order, meal_dict), axis=1)
答案 1 :(得分:1)
我喜欢你的问题,所以我在午休时间尝试一下。 我假设您可以选择数据集格式。我建议您将它们保留为列表。 这是我基于您的数据集。
orders = [['ORDB10489',[('Coffee', 2), ('Salad', 2), ('Chicken', 1), ('Steak', 1)],'Lunch',40],
['ORDZ00319',[('Fish&Chips', 1), ('Pasta', 3), ('Shrimp', 2)],'Dinner',57.5],
['ORDB00980',[('Pasta', 4), ('Fish&Chips', 3)],'Dinner',50.5],
['ORDC10404',[('Burger', 1), ('Salad', 1), ('Coffee', 1)],'Lunch',18]]
价格菜单:
lunch = [['Coffee',2.00],['Salad',6.50],['Burger',8.00],['Chicken',10.00],['Steak',13.00]]
dinner = [['Fish&Chips',7.50],['Pasta',7.00],['Shrimp',14.50]]
这是一个非常简单的代码,它基于格式[i] [j]对变量进行访问。例如:[('Coffee',2),('Salad',2),('Chicken',1),('Steak',1)]。它属于一个名为order的子列表,然后第一个元素由order [d] [0]访问,第二个元素由引用order [d] [1]访问。因此,order [0] [0]是咖啡,order [1] [0]是沙拉,order [0] [1]是2,order [2] [1]是1。
代码:
# reading all the orders, one by one
for o in range(len(orders)):
order_id = orders[o][0]
order = orders[o][1]
paid = [] # empty list for every new order
# reading all dishes, one by one
for d in range(len(order)):
dish = order[d][0]
quantity = order[d][1]
service = orders[o][2]
if service == 'Lunch':
for lu in range(len(lunch)):
if dish == lunch[lu][0]:
amount = quantity*(lunch[lu][1])
paid.append(amount)
else :
for di in range(len(dinner)):
if dish == dinner[di][0]:
amount = quantity*(dinner[di][1])
paid.append(amount) # adding to the paying list
due = sum(paid) #sum of dishes in the list
bill = orders[o][3]
print(order_id,due,bill)
输出:
ORDB10489 40.0 40
ORDZ00319 57.5 57.5
ORDB00980 50.5 50.5
ORDC10404 16.5 18