Как сгенерировать несколько последовательных одинковых 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 шт):
Ну вот так вроде будет быстрее, хотя разница в скорости всего в 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, а вписывать матрицы внутрь готовой уже матрицы. Хотя надо смотреть, как будет быстрее, но так не нужно будет делать много копий матрицы с комбинациями.