Как сделать X количество случайных наборов из 3 из столбца pandas?

#python-3.x #pandas

#python-3.x #pandas

Вопрос:

У меня есть столбец dataframe, который выглядит следующим образом (примерно 200 строк):

 col1
a
b
c
d
e
f
  

Я хочу создать новый фрейм данных с одним столбцом и 15 наборами из 3 случайных комбинаций элементов в столбце pandas. например:

new_df

 combinations:
(a,b,c)
(a,c,d)
(a,d,c)
(b,a,d)
(d,a,c)
(a,d,f)
(e,a,f)
(a,f,e)
(b,e,f)
(f,b,e)
(c,b,e)
(b,e,a)
(a,e,f)
(e,f,a)
  

В настоящее время код, который у меня есть, создает комбинацию всех возможных комбинаций и исчерпывает память, когда я пытаюсь добавить результаты в другой фрейм данных:

 import pandas as pd
from itertools import permutations 

df = pd.read_csv('')
combo = df['col1'].tolist()

perm = permutations(combo,3)
combinations = pd.DataFrame(columns=['combinations'])


list_ = []
for i in  list(perm): 
    combinations['combinations'] = i
    list_.append(i)
  

Как мне остановить наборы случайных комбинаций, чтобы остановиться на любом X количестве наборов или, в данном случае, 15 комбинациях из 3?

Комментарии:

1. @anon01 повторной выборки, если это возможно, не требуется.

2. вам нужны перечислимые комбинации или случайные комбинации?

3. @anon01 случайное — это то, что я хочу

4. вы также говорите комбинации, но показываете перестановки. Что это?

5. @anon01 комбинации. Меня не волнует порядок.

Ответ №1:

Причина, по которой вашему коду не хватает памяти, заключается именно в той части, в которой вы вызываете list(perm) . выполнение этого приведет к созданию ВСЕХ возможных перестановок. Поэтому, когда вы делаете

 for i in list(perm):
    ...
  

Вы говорите python создать список всех перестановок, а затем попытаться выполнить итерацию по этому списку. Вместо этого, если вы выполняете итерацию по тому generator , что permutations создает вызов (например for i in perm: , вместо for i in list(perm): ), вы можете просто выполнить итерацию по каждой перестановке, не сохраняя их все сразу в памяти. Итак, если вы прервете цикл for после того, как он повторится 15 раз, вы сможете достичь желаемого результата.

Однако, поскольку мы используем itertools , мы можем значительно упростить эту логику, используя islice для выполнения работы по получению первых 15 без явного написания for-loop и прерывания на 15-й итерации:

 import pandas as pd
from itertools import permutations, islice

# df = pd.read_csv('')
# combo = df['col1'].tolist()
combo = list("abcefg")

perm_generator = permutations(combo,3)

# get first 15 permutations without running the generator
first_15_perms = islice(perm_generator, 15)

# Store the first 15 permutations into a Series object
series_perms = pd.Series(list(first_15_perms), name="permutations")

print(series_perms)
0     (a, b, c)
1     (a, b, e)
2     (a, b, f)
3     (a, b, g)
4     (a, c, b)
5     (a, c, e)
6     (a, c, f)
7     (a, c, g)
8     (a, e, b)
9     (a, e, c)
10    (a, e, f)
11    (a, e, g)
12    (a, f, b)
13    (a, f, c)
14    (a, f, e)
Name: permutations, dtype: object
  

Если вы хотите, чтобы это было как один столбец в a DataFrame , вы можете использовать to_frame() метод:

 df_perms = series_perms.to_frame()

print(df_perms)
   permutations
0     (a, b, c)
1     (a, b, e)
2     (a, b, f)
3     (a, b, g)
4     (a, c, b)
5     (a, c, e)
6     (a, c, f)
7     (a, c, g)
8     (a, e, b)
9     (a, e, c)
10    (a, e, f)
11    (a, e, g)
12    (a, f, b)
13    (a, f, c)
14    (a, f, e)
  

Комментарии:

1. Ваше объяснение очень полезно. Однако, когда я запускаю series_perms = pd.Series(first_15_perms, name="permutations") , я получаю сообщение об ошибке TypeError: object of type 'itertools.islice' has no len() . Я пытаюсь исправить это сейчас

2. Вы можете создать временный список. Вероятно, это функция в новой версии pandas, которая позволяет генератору в Series . Попробуйте: pd.Series(list(first_15_perms), name="permutations")

3. Я думал, вас интересует случайная последовательность

Ответ №2:

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

 def newFrame(df: pd.DataFrame, srccol: int, cmbs: int, rows: int) -> pd.DataFrame:
    il = df[srccol].values.tolist()
    nw_df = pd.DataFrame()
    data = []
    for r in range(rows):
        rd =[]
        for ri in range(cmbs):
            rd.append(rnd.choice(il))
        data.append(tuple(rd))
    nw_df['Combinations'] = data
    return nw_df
  

Который при передаче a a df, как показано в вашем примере, в виде:

 new_df = newFrame(df, 0, 3, 15)  
  

Производит:

     Combinations
0   (a, f, e)
1   (a, d, f)
2   (b, c, d)
3   (a, a, d)
4   (f, b, c)
5   (e, b, b)
6   (e, e, d)
7   (c, f, f)
8   (f, e, b)
9   (d, c, e)
  

Комментарии:

1. Эй, просто хотел поблагодарить вас, но я выбрал вышеупомянутое решение