Комбинация значений в Pandas по условию

Есть такая задача. Дан номер заказа и разные продукты из этого заказа:

введите сюда описание изображения

Мне нужно сделать второй DF (или series) с сочетаниями продуктов, НО сочетания не из всего списка, а по заказам. Например, сочетания заказа 100 будут такие: "Рис - Гречка, Рис - Хлеб Черный, Гречка - Рис, Гречка - Хлеб Черный, Хлеб Черный - Рис, Хлеб Черный - Гречка, Рис - Рис, Гречка - Гречка, Хлеб Черный - Хлеб Черный". Из заказа 102 - свои сочетания, и т.д. Значения, где есть 2 слова одинаковые, например, "Гречка - Гречка" нужно будет удалить.

Пробовал с помощью itertools, но не знаю как добавить условие, чтобы сочетания были ТОЛЬКО по заказу, а не по всему DF: df2 = pd.DataFrame((product(df['Product'], df['Product'])))

введите сюда описание изображения

Тут пример учебный, в реальном - заказов больше сотни.

Сам файл

Если кто знает, как помочь в данном примере, был бы благодарен!


Ответы (1 шт):

Автор решения: D.Vinogradov

Через itertools подход верный.

Можно попробовать следующим образом:

from itertools import permutations

df = pd.read_excel('/*/tes2.xlsx')

Сгруппируем, применим itertools и сбросим индекс:

df.groupby('Order').agg(new=('Product', lambda x: list(permutations(x, 2)))).reset_index()

Получим что-то вроде этого:

Order                                                                                                      new
0    100  [(Рис, Гречка), (Рис, Хлеб Черный), (Гречка, Рис), (Гречка, Хлеб Черный), (Хлеб Черный, Рис), (Хлеб Черный, Гречка)]
1    101                  [(Яблоко, Гречка), (Яблоко, Кофе), (Гречка, Яблоко), (Гречка, Кофе), (Кофе, Яблоко), (Кофе, Гречка)]
2    102          [(Рис, Хлеб Черный), (Рис, Кофе), (Хлеб Черный, Рис), (Хлеб Черный, Кофе), (Кофе, Рис), (Кофе, Хлеб Черный)]

Если нужно разбить именно по сочетаниям, то:

df.groupby('Order').agg(new=('Product', lambda x: list(permutations(x, 2)))).reset_index().explode('new')

   Order                    new
0    100          (Рис, Гречка)
0    100     (Рис, Хлеб Черный)
0    100          (Гречка, Рис)
0    100  (Гречка, Хлеб Черный)
0    100     (Хлеб Черный, Рис)
0    100  (Хлеб Черный, Гречка)
1    101       (Яблоко, Гречка)
1    101         (Яблоко, Кофе)
1    101       (Гречка, Яблоко)
1    101         (Гречка, Кофе)
1    101         (Кофе, Яблоко)
1    101         (Кофе, Гречка)
2    102     (Рис, Хлеб Черный)
2    102            (Рис, Кофе)
2    102     (Хлеб Черный, Рис)
2    102    (Хлеб Черный, Кофе)
2    102            (Кофе, Рис)
2    102    (Кофе, Хлеб Черный)

p.s. можно и еще раз скинуть индекс и tuple перевести в list или строку, но это уже как удобно и совсем другая история.

→ Ссылка