Extrai uma amostra aleatória de N linhas com base no padrão

2

Eu tenho um arquivo formatado assim:

train/t/temple/east_asia/00000025.jpg 94
train/t/temple/east_asia/00000865.jpg 94
...
train/s/swamp/00000560.jpg 92
train/s/swamp/00000935.jpg 92
....
train/m/mountain/00000428.jpg 68
train/m/mountain/00000126.jpg 68

O último número é o número da turma. Eu tenho 50 classes diferentes e cada classe tem 1.000 linhas. Gostaria de obter uma amostra aleatória do tamanho N de cada classe e armazenar o resultado em outro arquivo de texto.

    
por apples-oranges 20.03.2016 / 22:58

2 respostas

6

Como suas linhas são agrupadas por classe, você poderia (com gnu tools) split o arquivo em partes e usar a opção --fiter para canalizar cada peça para shuf para extrair N linhas aleatórias a partir dele:

split --filter='shuf -n N' infile > outfile

Observe que split é padronizado para 1000 linhas - o que é necessário neste caso específico. Se os requisitos mudarem, você terá que passar o número de linhas via -l
por exemplo. para dividir em pedaços de 200 linhas e extrair 30 linhas aleatórias de cada peça:

split -l 200 --filter='shuf -n 30' infile > outfile
    
por 20.03.2016 / 23:51
1

Você deve conseguir fazer isso com apenas uma chamada de comando awk :

Para selecionar p = 50 linhas aleatoriamente de cada n = 1000 linhas:

awk -v n=1000 -v p=50 '
  BEGIN {srand(); remaining = p}
  NR > n {remaining = p; NR = 1}
  rand()*(n + 1 - NR) < remaining {
    print; remaining--
  }' < your-file
    
por 17.11.2017 / 16:32