Как сгенерировать несколько последовательных одинковых combinations со своим уникальным id и сохранить полученный результат в df?

Как с помощью однострочного выражения можно сгенерировать несколько последовательных одинковых combinations со своим уникальным id и сохранить полученный результат в df?

Пример рабочего кода, который хотелось бы упростить и увеличить скорость выполнения Столбец col5 содержит уникальных идентификатор сгенерированного набора gc

import itertools as iter
import pandas as pd 

gc = iter.combinations(range(1, 7), 4)
df = pd.DataFrame(gc, columns=['col1', 'col2', 'col3', 'col4'])

dfr = pd.DataFrame()
for i in range(1,4):
    dfi = df.copy()
    dfi['col5'] = i
    dfr = pd.concat([dfr, dfi])

dfr = dfr.reset_index().drop(columns='index')
print(dfr)

Ожидаемый результат

      col1  col2  col3  col4  col5
0      1     2     3     4     1
1      1     2     3     5     1
2      1     2     3     6     1
3      1     2     4     5     1
4      1     2     4     6     1
5      1     2     5     6     1
6      1     3     4     5     1
7      1     3     4     6     1
8      1     3     5     6     1
9      1     4     5     6     1
10     2     3     4     5     1
11     2     3     4     6     1
12     2     3     5     6     1
13     2     4     5     6     1
14     3     4     5     6     1
15     1     2     3     4     2
16     1     2     3     5     2
17     1     2     3     6     2
18     1     2     4     5     2
19     1     2     4     6     2
20     1     2     5     6     2
21     1     3     4     5     2
22     1     3     4     6     2
23     1     3     5     6     2
24     1     4     5     6     2
25     2     3     4     5     2
26     2     3     4     6     2
27     2     3     5     6     2
28     2     4     5     6     2
29     3     4     5     6     2
30     1     2     3     4     3
31     1     2     3     5     3
32     1     2     3     6     3
33     1     2     4     5     3
34     1     2     4     6     3
35     1     2     5     6     3
36     1     3     4     5     3
37     1     3     4     6     3
38     1     3     5     6     3
39     1     4     5     6     3
40     2     3     4     5     3
41     2     3     4     6     3
42     2     3     5     6     3
43     2     4     5     6     3
44     3     4     5     6     3

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

Автор решения: CrazyElf

Ну вот так вроде будет быстрее, хотя разница в скорости всего в 2 раза что ли на вашем примере. На более крупных таблицах, возможно, разница будет существеннее:

import itertools as iter
import pandas as pd 

gc = iter.combinations(range(1, 7), 4)
df = pd.DataFrame(gc, columns=['col1', 'col2', 'col3', 'col4'])

dfr = pd.concat([df for _ in range(1,4)]).reset_index().drop(columns='index')
dfr['col5'] = [i for i in range(1,4) for _ in range(df.shape[0])]
print(dfr)

Пояснения:

  • Объединение датафреймов лучше вынести за цикл. Когда датафрейм всё время растёт внутри цикла, это сильно замедляет процесс. Гораздо быстрее будет, если делать concat сразу всех накопленных датафреймов разом. А поскольку они у вас одинаковые (за исключением последнего столбца), отпадает также надобность в их копировании, можно датафрейм сам с собой сконкатенировать нужное число раз
  • Последнюю колонку можно заполнить также разово и уже после конкатенации, это опять должно быть быстрее и проще, чем вписывать её отдельно в каждый датафрейм и потом это всё конкатенировать.

Update: Ещё быстрее будет, если делать через Numpy, а в DataFrame превращать в самом конце (если это вообще нужно). Примерно так:

import itertools as iter
import numpy as np
import pandas as pd 

gc = np.array([list(t) for t in iter.combinations(range(1, 7), 4)])
col5 = np.array([i for i in range(1,4) for _ in range(gc.shape[0])]).reshape(-1,1)
dfm = np.hstack((np.vstack(tuple(gc for _ in range(1,4))),col5))
dfr = pd.DataFrame(dfm, columns=['col1', 'col2', 'col3', 'col4','col5'])
print(dfr)

Тут можно (и нужно) оптимизировать и дальше, например, создать сразу матрицу Numpy нужного размера и делать не vstack и hstack, а вписывать матрицы внутрь готовой уже матрицы. Хотя надо смотреть, как будет быстрее, но так не нужно будет делать много копий матрицы с комбинациями.

→ Ссылка