Как найти наиболее распространенные комбинации элементов в сгруппированном кадре данных? - PullRequest
2 голосов
/ 10 июля 2019

У меня есть такой фрейм данных:

pd.DataFrame([{"order_id": 1234, "product": "milk"},
              {"order_id": 1234, "product": "butter"},
             {"order_id": 4321, "product": "bread"}, 
             {"order_id": 4321, "product": "milk"},
             {"order_id": 4321, "product": "butter"},
             {"order_id": 1111, "product": "corn"},
             {"order_id": 1111, "product": "cereal"},
             {"order_id": 8888, "product": "milk"}])

    order_id    product
0   1234    milk
1   1234    butter
2   4321    bread
3   4321    milk
4   4321    butter
5   1111    corn
6   1111    cereal
7   8888    milk

Мне нужно найти наиболее распространенную комбинацию продуктов, без необходимости определять, сколько продуктов положить в эти комбинации.

В этом примере показано, как вернуть молоко и масло как два наиболее купленных вместе итена.

Я пытался сгруппировать их по order_id, но не смог найти решение для получения комбинаций внутри групп.

Ответы [ 2 ]

3 голосов
/ 10 июля 2019

Мы можем найти пары продуктов по merge и groupby.size:

# merge on id to pair up the products
new_df = df.merge(df, on='order_id')

# first thing is to drop identical products
(new_df[new_df['product_x'].lt(new_df['product_y'])]
    .groupby(['order_id', 'product_x', 'product_y'])              # group
    .size()            # count (id, prod1, prod2)
    .sum(level=[1,2])  # sum over (prod1, prod2)
    .idxmax()          # get (prod1, prod2) with max count
)

дает вам

('butter', 'milk')
1 голос
/ 10 июля 2019

itertools.combinations и pandas.Series.mode

from itertools import combinations

pd.Series.mode([
    t for _, d in df.groupby('order_id').product
    for t in combinations(d, 2)
])

0    (milk, butter)
dtype: object

collections.Counter

Такой же ответ, как и выше, но с использованием Counter вместо pandas.Series.mode

from itertools import combinations
from collections import Counter

Counter([
    t for _, d in df.groupby('order_id').product
    for t in combinations(d, 2)
]).most_common(1)

[(('milk', 'butter'), 2)]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...