Как вы рандомизируете строки эффективным способом памяти? - PullRequest
0 голосов
/ 05 декабря 2018

У меня есть текст, как показано ниже, и его размер составляет около 6 ГБ.Я хочу сохранить строки до #CHROM без изменений, но я хочу перетасовать все строки ниже строки #CHROM.Есть ли эффективный способ памяти?

##contig=<ID=chrX,length=155270560,assembly=hg19>
##contig=<ID=chrY,length=59373566,assembly=hg19>
##contig=<ID=chrM,length=16571,assembly=hg19>
##reference=file:///dmf/
##source=SelectVariants
#CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO    FORMAT
chr1    14165   .       A       G       220.12  VQSRTrancheSNP99.90to10
chr1    14248   .       T       G       547.33  VQSRTrancheSNP99.90to10
chr1    14354   .       C       A       2942.62 VQSRTrancheSNP99.90to10
chr1    14374   .       A       G       17.90   VQSRTrancheSNP99.90to10

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

##contig=<ID=chrX,length=155270560,assembly=hg19>
##contig=<ID=chrY,length=59373566,assembly=hg19>
##contig=<ID=chrM,length=16571,assembly=hg19>
##reference=file:///dmf/
##source=SelectVariants
#CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO    FORMAT
chr1    14354   .       C       A       2942.62 VQSRTrancheSNP99.90to10
chr1    14248   .       T       G       547.33  VQSRTrancheSNP99.90to10
chr1    14374   .       A       G       17.90   VQSRTrancheSNP99.90to10
chr1    14165   .       A       G       220.12  VQSRTrancheSNP99.90to10

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018

Вот один в awk:

awk -v seed=$RANDOM '              # get a random seed to srand()
BEGIN {
    srand(seed)                    
}
/^#/ {                             # print all # starting, no need to store them to mem
    print                          # this could be more clever but not the point
    next                           # in this solution
}
{
    r=rand()                        # get a random value for hash key
    a[r]=a[r] (a[r]==""?"":ORS) $0  # hash to a, append if key collision
}
END {
    for(i in a)                     # in the end print in awk implementation default order
        print a[i]                  # randomness was created while hashing
}' file

Выход AN:

##contig=<ID=chrX,length=155270560,assembly=hg19>
##contig=<ID=chrY,length=59373566,assembly=hg19>
##contig=<ID=chrM,length=16571,assembly=hg19>
##reference=file:///dmf/
##source=SelectVariants
#CHROM  POS     ID      REF     ALT     QUAL    FILTER  INFO    FORMAT
chr1    14165   .       A       G       220.12  VQSRTrancheSNP99.90to10
chr1    14354   .       C       A       2942.62 VQSRTrancheSNP99.90to10
chr1    14248   .       T       G       547.33  VQSRTrancheSNP99.90to10
chr1    14374   .       A       G       17.90   VQSRTrancheSNP99.90to10

Он загрузит все не # записи, начинающиеся в память.Если вы попробуете это, пожалуйста, сообщите нам, насколько большой образ памяти увеличивается.

Обновление :

Вот еще одна небольшая модификация вышеприведенного:

BEGIN {
    srand(seed)
}
/^#/ {
    print
    next
}
{
    r=rand()
    a[r]=a[r] (a[r]==""?"":ORS) $0
}
NR>1000 {             # the first 1000 records are hashed above
    for(i in a) {     # after that 
        print a[i]    # a "random" one is printed
        delete a[i]   # and deleted from the hash
        break         # only a 1000 records is kept in memory
    }
}
END {
    for(i in a)
        print a[i]
}

Поскольку я использую NR, который включает в себя также # начальные записи, поэтому 1000 записей - это не точное количество записей в хэше.Выберите значение по своему вкусу.

Вот пример вывода с NR>10 и seq 1 20:

$ seq 1 20 | awk -v seed=$RANDOM -f script.awk  
3
9
13
2
1
16
17
14
10
20
15
7
19
5
18
12
11
6
4
8
0 голосов
/ 05 декабря 2018

Поскольку вы работаете в Linux, у вас, вероятно, есть GNU sort -R для рандомизации.

Сортировка GNU автоматически использует дисковое пространство вместо ОЗУ, когда это необходимо, поэтому она может сортировать / рандомизировать сотни гигабайт в системах.с гораздо меньшим количеством оперативной памяти.

0 голосов
/ 05 декабря 2018

Я бы разделил файл по вашим критериям, использовал бы shuf для второго чанка и снова соединил их вместе.Я не могу представить себе ват с эффективным использованием памяти, который бы избежал расщепления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...