Amostragem repetida do Python sem substituição de uma determinada lista [duplicado]
dada uma lista de (por exemplo) inteiros, gostaria de obter nelementos de amostra sem substituição, remover os itens de amostra da lista original e repetir este processo até que agora os elementos na lista original permaneçam. Retornando uma lista de round(len(list)/n).
Eu sei sobre random.sample(), porém não encontrei uma implementação para amostragem repetida sem substituição. Meu pseudocódigo abaixo não inclui a remoção dos elementos de amostra da lista original. No entanto, enquanto escrevo esta função, fico me perguntando se não há algo assim já implementado ou uma solução mais elegante para isso?
Pseudo-código
def repeated_sample_without_replacement(my_list, n):
# where n = number of samples,
k = int(len(my_list) / n)
if len(my_list)%n != 0:
samples = np.repeat(n,k)
samples = np.append(samples, len(my_list) % n)
else:
samples = np.repeat(n,k)
k = len(my_list) / n
out = []
for s in samples:
out.append(random.sample(my_list, s))
# remove the now sample elements from my_list
return out
x = repeated_sample_without_replacement(ids,10)
print(x)
Dados de exemplo
# Sample Data
ids_clean = [*range(1,40)]
In[71]: # Remove Some ID to Better Represent my Purpose
ids = ids_clean[:12] + ids_clean[13:26] + ids_clean[27:]
ids
Out[73]:
[1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39]
len(ids)
Out[74]: 37
Resultado Desejado
[[1,4,5,6..],[2,8,9,...],[13,15,16,...][27,10,..]]
Respostas
Seu código mostra que você está tentando obter uma amostra de toda a lista fornecida. Então, apenas random.shuffleuma vez e, em seguida, divida em pedaços. Ou mesmo apenas fatias com passo n, o que torna mais fácil:
from random import shuffle
def repeated_sample_without_replacement(my_list, n):
shuffle(my_list)
return [my_list[i::n] for i in range(n)]
Demo:
>>> repeated_sample_without_replacement(list(range(10)), 3)
[[7, 5, 0, 1], [2, 6, 8], [4, 3, 9]]
Observe que isso produz exatamente namostras. Nem mais nem menos como o seu.
Demonstração sua :
>>> repeated_sample_without_replacement(list(range(10)), 3)
[[3, 0, 2], [5, 4, 6], [6, 1, 7], [3]]
>>> repeated_sample_without_replacement(list(range(10)), 13)
[[1, 0, 3, 7, 8, 2, 5, 4, 9, 6]]