Случайным образом выберите строки из файла, не хлебая его с Unix

попробуйте это:

var data = map[string]map[string]string{
    "ticket": map[string]string{},
    "totalpage": map[string]string{},
    "c": map[string]string{},
}

data["ticket"]["w"] = "vrniairvnai"
data["totalpage"]["w"] = "ten"
fmt.Println(data)

var data2 = make(map[string]interface{})
data2["data"] = data
data2["int"] = 10
fmt.Println(data2)
51
задан Steven Huwig 27 March 2009 в 22:06
поделиться

6 ответов

если бы у Вас есть это много строк, действительно ли Вы уверены, что хотите точно 1%, или статистическая оценка была бы достаточно?

В том втором случае просто рандомизируйте в 1% в каждой строке...

awk 'BEGIN {srand()} !/^$/ { if (rand() <= .01) print $0}'

Если Вы хотели бы строку заголовка плюс случайная выборка строк после, используйте:

awk 'BEGIN {srand()} !/^$/ { if (rand() <= .01 || FNR==1) print $0}'
86
ответ дан Tom Morris 7 November 2019 в 09:42
поделиться

Вы использовали awk, но я не знаю, требуется ли он. Если это не, вот тривиальный способ сделать w/жемчуг (и не загружая весь файл в память):

cat your_file.txt | perl -n -e 'print if (rand() < .01)'

(более простая форма, из комментариев):

perl -ne 'print if (rand() < .01)' your_file.txt 
53
ответ дан Gregg Lind 7 November 2019 в 09:42
поделиться

Это должно работать над большей частью любой машины GNU/Linux.

$ shuf -n $(( $(wc -l < $file) / 100)) $file

Я был бы удивлен, было ли управление памятью сделано неуместно GNU shuf команда.

16
ответ дан ashawley 7 November 2019 в 09:42
поделиться

Я написал этот точный код в Простофиле - Вы находитесь в удаче. Это длинно частично, потому что это сохраняет входной порядок. Существуют, вероятно, улучшения производительности, которые могут быть сделаны.

Этот алгоритм корректен, не зная входного размера заранее. Я отправил Розеттский камень здесь об этом. (Я не отправил эту версию, потому что она делает ненужные сравнения.)

Исходный поток: Отправленный для Вашего обзора - случайная выборка в awk.

# Waterman's Algorithm R for random sampling
# by way of Knuth's The Art of Computer Programming, volume 2

BEGIN {
    if (!n) {
        print "Usage: sample.awk -v n=[size]"
        exit
    }
    t = n
    srand()

}

NR <= n {
    pool[NR] = $0
    places[NR] = NR
    next

}

NR > n {
    t++
    M = int(rand()*t) + 1
    if (M <= n) {
        READ_NEXT_RECORD(M)
    }

}

END {
    if (NR < n) {
        print "sample.awk: Not enough records for sample" \
            > "/dev/stderr"
        exit
    }
    # gawk needs a numeric sort function
    # since it doesn't have one, zero-pad and sort alphabetically
    pad = length(NR)
    for (i in pool) {
        new_index = sprintf("%0" pad "d", i)
        newpool[new_index] = pool[i]
    }
    x = asorti(newpool, ordered)
    for (i = 1; i <= x; i++)
        print newpool[ordered[i]]

}

function READ_NEXT_RECORD(idx) {
    rec = places[idx]
    delete pool[rec]
    pool[NR] = $0
    places[idx] = NR  
} 
19
ответ дан Community 7 November 2019 в 09:42
поделиться

Вместо того, чтобы ожидать до конца для случайного выбора 1% строк сделайте это каждые 100 строк в "/^ $ /". Тем путем Вы только остаетесь на 100 линиях за один раз.

1
ответ дан Travis Jensen 7 November 2019 в 09:42
поделиться

Вы могли сделать это в двух передачах:

  • Пробегите файл однажды, только для подсчета сколько строк, там
  • Случайным образом выберите номера строки строк, которые Вы хотите распечатать, храня их в отсортированном списке (или набор)
  • Пробегите файл еще раз и выберите строки в выбранных положениях

Пример в Python:

fn = '/usr/share/dict/words'

from random import randint
from sys import stdout

count = 0
with open(fn) as f:
   for line in f:
      count += 1

selected = set()
while len(selected) < count//100:
   selected.add(randint(0, count-1))

index = 0
with open(fn) as f:
   for line in f:
      if index in selected:
          stdout.write(line)
      index += 1
3
ответ дан sth 7 November 2019 в 09:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: