Пользовательская группировка для всех возможных групп в кадре данных с пропущенными значениями - PullRequest
0 голосов
/ 19 марта 2019

У меня есть датафрейм, представляющий набор продуктов. Мне нужно найти все дубликаты продуктов в этих продуктах. Если продукты имеют одинаковые product_type, color и size ->, они являются дубликатами. Это была бы простая строка df.groupby('product_type','color','size'), если бы у меня не было проблемы: некоторые значения отсутствуют. Теперь мне нужно найти все возможные группы товаров, которые могут быть дубликатами между собой. Это означает, что некоторые элементы могут появляться в нескольких группах.

Позвольте мне проиллюстрировать:

import pandas as pd


def main():
    df = pd.DataFrame({'product_id': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11],
                       'product_type': ['shirt', 'shirt', 'shirt', 'shirt', 'shirt', 'hat', 'hat', 'hat', 'hat', 'hat', 'hat', ],
                       'color': [None, None, None, 'red', 'blue', None, 'blue', 'blue', 'blue', 'red', 'red', ],
                       'size': [None, 's', 'xl', None, None, 's', None, 's', 'xl', None, 'xl', ],
                       })
    print df   

if __name__ == '__main__':
    main()

для этого кадра данных:

enter image description here

Мне нужен этот результат - список возможных дублирующих продуктов для каждой возможной группы (возьмите только самые большие супергруппы):

![enter image description here

Так, например, давайте возьмем "рубашку" с id=1 этот продукт не имеет цвета или размера, поэтому он может появиться в возможной «группе дубликатов» вместе с рубашкой № 2 (которая имеет размер «s», но не имеет цвета) и рубашкой № 4 (которая имеет цвет «красный», но имеет не имеют размера). Таким образом, эти три рубашки (1,2,4), возможно, являются дубликатами того же цвета "красный" и размера "с".

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

Есть ли способ получить желаемый результат?

1 Ответ

0 голосов
/ 19 марта 2019

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

from itertools import product

def get_possible_combinations(df, columns=['size',  'product_type', 'color']):
    col_vals = []
    for col in columns:
        col_vals.append(df.loc[~df.loc[:, col].isnull(), col].unique().tolist())
    for comb in product(*col_vals):
        df_ = df.copy()
        for val, col in zip(comb, columns):
            df_.loc[:, col].fillna(val, inplace=True)
        yield df_.groupby(columns)

Итак, мы можем применить эту функцию к df:

resulting_groups = []
for g in get_possible_combinations(df):
    sorted_groups = [ind.tolist() for a, ind in g.groups.items()]
    resulting_groups.append(sorted_groups)

resulting_groups = sum(resulting_groups, [])
sorted(list(set(map(tuple, resulting_groups))), key=len, reverse=True)

[(5, 6, 7), (0, 2, 3), (0, 1, 3), (0, 1, 4), (0, 2, 4), (5, 9), (6, 7), (6, 8), (5, 7), (9, 10), (1,), (2,), (8,), (3,), (9,), (4,), (10,), (5,), (7,)]

Это почти то же самое, что вы ищете.

...