Разделите список на группы, указав идентификатор группы - PullRequest
1 голос
/ 07 мая 2020

У меня есть список, например:

my_list = [1,2,3,4,5,6,7]

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

group_id = [1,1,1,2,2,2,2]

где последняя группа содержит еще 1 элемент из-за того, что my_list содержит простое количество элементов.

Вот все возможные разделения, от 7 групп до 1:

group_id = [1,2,3,4,5,6,7]  # 7 groups, 7 elements
group_id = [1,1,2,3,4,5,6]  # 6 groups, 7 elements
group_id = [1,1,2,2,3,4,5]  # 5 groups, 7 elements
group_id = [1,1,2,2,3,3,4]  # 4 groups, 7 elements
group_id = [1,1,1,2,2,2,3]  # 3 groups, 7 elements
group_id = [1,1,1,2,2,2,2]  # 2 groups, 7 elements
group_id = [1,1,1,1,1,1,1]  # 1 group, 7 elements.

Проблема в том, что я не знаю, как обеспечить выполнение этого условия, что группы должны быть более или менее равные по размеру. Это должно работать для любой длины списка (не только 7) и предоставить мне group_id списки заданного количества групп (от 1 до len(my_list)).

EDIT:

Это вроде "несколько" работает, хотя и не полностью:

import math

my_list = [1,2,3,4,5,6,7]
n_groups = 3


k = math.ceil(len(my_list)/n_groups)
chunks = [my_list[x:x+k] for x in range(0, len(my_list), k)]
group_id_nested = [[chunks.index(i)+1]*len(i) for i in chunks]
group_id = [item for sublist in group_id_nested for item in sublist]

Ответы [ 2 ]

1 голос
/ 07 мая 2020

Если вам разрешено использовать numpy, вы можете использовать numpy .linspace для этой задачи следующим образом:

import numpy as np
list_size = 7
for n in range(1,list_size+1):
    group_ids = list(map(int,map(round,np.linspace(1,n,num=list_size))))
    print(group_ids)

Вывод:

[1, 1, 1, 1, 1, 1, 1]
[1, 1, 1, 2, 2, 2, 2]
[1, 1, 2, 2, 2, 3, 3]
[1, 2, 2, 2, 3, 4, 4]
[1, 2, 2, 3, 4, 4, 5]
[1, 2, 3, 4, 4, 5, 6]
[1, 2, 3, 4, 5, 6, 7]

Идея проста: я получаю числа с равными интервалами (с плавающей точкой) (list_size из них) от 1 (включительно) до n (включительно), а затем получаю ближайшее целое число для каждого (примечание использование round). Как вы можете видеть в каждой строке вывода, разница между любыми двумя размерами групп (количество встречаемости данного числа) всегда равно или меньше 2.

0 голосов
/ 07 мая 2020

Без numpy:

import math
listy = [1,2,3,4,5,6,7]
groupnum = 6

smallnum = math.floor(len(listy)/groupnum)
bignum = math.ceil(len(listy)/groupnum)

grouped = []
for c,e in enumerate(range(1,groupnum+1)):
    if c<(len(listy)/groupnum - smallnum)*groupnum:
        grouped+=[e]*bignum
    else:
        grouped+=[e]*smallnum
grouped=grouped[0:len(listy)]
print(grouped)

Кроме того, он распределяет их равномерно. Например, для разделения на 4 группы будет выполнено [1, 1, 2, 2, 3, 3, 4] вместо [1, 2, 2, 2, 3, 4, 4].

...