Python - [Pandas / Lists / Numpy?] Выбор рецептов случайным образом, чтобы создать меню с диапазоном питательных веществ

Я пытаюсь создать для себя простой скрипт, в котором у меня есть база данных с моими собственными рецептами, и я создаю дневное меню на неделю. Это пример базы данных:

recipe_data = {'Recipe': ['Macaroni', 'Mashed_potato', 'Risotto', 'Sandwich', 'Tuna_salad', 'Pancakes', 'Overnight_oats'],
        'Recipe_type': ['Dinner', 'Dinner', 'Dinner',  'Lunch', 'Lunch', 'Breakfast', 'Breakfast'],
        'Protein': [50, 40, 30, 20, 20, 10, 10],
        'Carbohydrates': [100, 80, 60, 50, 40, 30, 20]}

df = pd.DataFrame(recipe_data)

           Recipe Recipe_type  Protein  Carbohydrates
0        Macaroni      Dinner       50            100
1   Mashed_potato      Dinner       40             80
2         Risotto      Dinner       30             60
3        Sandwich       Lunch       20             40
4      Tuna_salad       Lunch       20             40
5        Pancakes   Breakfast       10             20
6  Overnight_oats   Breakfast       10             20

Я хочу создать функцию, которую я мог бы сказать: создать случайное меню [комбинация завтрака, обеда и ужина] с суммой сочетания белков между 65 - 85 и суммой сочетаний углеводов между: 135 - 165. В этом примере это сгенерирует вариант как:

           Recipe Recipe_type  Protein  Carbohydrates
0        Macaroni      Dinner       50            100
3        Sandwich       Lunch       20             40
5        Pancakes   Breakfast       10             20

Я очень плохо знаком с Python, и я видел некоторые ответы, которые выглядят как мой вопрос, но не мог найти способ сделать это. Поэтому любая помощь приветствуется. До сих пор я дошел только до этого:

print(df.groupby(['Recipe_type'])['Protein'].apply(np.random.choice).reset_index())
  Recipe_type  Protein
0   Breakfast       10
1      Dinner       30
2       Lunch       20

(очевидно, это не печатает все столбцы и не учитывает сумму питательных веществ ..)

вполне может быть, что я на самом деле должен работать со списками или словарями, так что эти обвинения могут мне сильно помочь :)

Всего 1 ответ


Один из способов сделать это - перекрестное слияние и фильтрация:

df['dummy'] =1

(df[df.Recipe_type=='Breakfast']                     # all breakfast recipes
    .merge(df[df.Recipe_type=='Lunch'], on='dummy')  # cross merge with lunch
    .merge(df[df.Recipe_type=='Dinner'], on='dummy') # cross merge with dinner
    .assign(Total_Protein=lambda x: x.filter(like='Protein').sum(1))  # calculate total protein
    .assign(Total_Carbonhydrates=lambda x:x.filter(like='Carbohydrates').sum(1)) # calculate total carbonhydrates
    .query(ཽ<=Total_Protein<=85 & 135<=Total_Carbonhydrates<=165')  # filter with given criteria
)

И вы получите информационный Recipe_x, Recipe_y, Recipe где Recipe_x, Recipe_y, Recipe представляют блюда с желаемым общим количеством Protein и Carbonhydrates .


Есть идеи?

10000