Python: получить комбинации уникальных значений из столбцов datafame - PullRequest
3 голосов
/ 31 марта 2020

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

id  a   b   c   d   e
0   a10 a11 a12 a13 a14
1   a10 a21 a12 a23 a24
2   a30 a21 a12 a33 a14
3   a30 a21 a12 a43 a44
4   a10 a51 a12 a53 a14

, и я хочу получить все уникальные списки комбинаций длины 'x' из фрейма данных. Если длина равна 3, то некоторые из комбинаций будут:

[[a10,a11,a12],[a10,a21,a12],[a10,a51,a12],[a30,a11,a12],[a30,a21,a12],[a30,a51,a12],
[a11,a12,a13],[a11,a12,a23],[a11,a12,a33],[a11,a12,a43],[a11,a12,a53],[a21,a12,a13]....]

Есть только 2 ограничения:

1. Length of combination lists should be equal to the 'x'
2. In one combination, there can be at max only 1 unique value from a column of dataframe.

Ниже приведен минимальный фрагмент кода, который создает кадр данных. Любая помощь будет высоко ценится. Спасибо!

data_dict={'a':['a10','a10','a30','a30','a10'],
          'b':['a11','a21','a21','a21','a51'],
          'c':['a12','a12','a12','a12','a12'],
          'd':['a13','a23','a33','a43','a53'],
          'e':['a14','a24','a14','a44','a14']}
df1=pd.DataFrame(data_dict)

Ответы [ 2 ]

3 голосов
/ 31 марта 2020

Чтобы получить уникальное значение для каждого столбца:

aa = [list(product(np.unique(df1[col1]), 
                   np.unique(df1[col2]), 
                   np.unique(df1[col3]))) 
      for col1, col2, col3 in list(combinations(df1.columns, 3))]

Старый ответ

Сначала мы сгладим вашу матрицу в массив 1d с помощью np.flatten и получить уникальные значения с помощью np.unique, затем мы используем itertools.combinations:

from itertools import combinations

a = np.unique(df1.to_numpy().flatten())
aa = set(combinations(a, 3))

{('a10', 'a11', 'a12'),
 ('a10', 'a11', 'a13'),
 ('a10', 'a11', 'a14'),
 ('a10', 'a11', 'a21'),
 ('a10', 'a11', 'a23'),
 ('a10', 'a11', 'a24'),
 ('a10', 'a11', 'a30'),
 ('a10', 'a11', 'a33'),
 ('a10', 'a11', 'a43'),
 ('a10', 'a11', 'a44'),
 ('a10', 'a11', 'a51'),
 ('a10', 'a11', 'a53'),
 ('a10', 'a12', 'a13'),
 ('a10', 'a12', 'a14'),
 ...

Или для фактического получения списков (что менее эффективно):

from itertools import combinations

a = np.unique(df1.to_numpy().flatten())
aa = [list(x) for x in set(combinations(a, 3))]

[['a12', 'a33', 'a51'],
 ['a11', 'a12', 'a13'],
 ['a10', 'a11', 'a21'],
 ['a10', 'a23', 'a24'],
 ['a12', 'a14', 'a24'],
 ['a14', 'a43', 'a53'],
 ['a11', 'a21', 'a53'],
 ['a10', 'a12', 'a24'],
 ['a12', 'a21', 'a44'],
 ['a12', 'a30', 'a51'],
 ['a14', 'a23', 'a30'],
 ...
2 голосов
/ 31 марта 2020

Используйте combinations с фильтрацией по set с, созданной каждым столбцом DateFrame для второго условия:

from  itertools import combinations

L = [set(df[x]) for x in df]
a = [x for x in combinations(np.unique(df.values.ravel()), 3) 
     if all(len(set(x).intersection(y)) < 2 for y in L)]
...