Alles ist im Titel. Ich frage mich, ob jemand einen schnellen und vernünftigen Speicherbedarf kennt, um alle Zeilen einer 3 Millionen Zeilen Datei zufällig zu mischen. Ich denke, es ist nicht möglich mit einem einfachen vim-Befehl, also ein einfaches Skript mit Python. Ich habe mit Python versucht, indem ich einen Zufallszahlengenerator benutzt habe, aber es ist mir nicht gelungen, einen einfachen Ausweg zu finden.Mischen Sie nach dem Zufallsprinzip Linien von 3 Millionen Zeilen Datei
Antwort
import random
with open('the_file','r') as source:
data = [ (random.random(), line) for line in source ]
data.sort()
with open('another_file','w') as target:
for _, line in data:
target.write(line)
Das sollte es tun. 3 Millionen Zeilen passen in den Speicher der meisten Maschinen, es sei denn, die Zeilen sind RIESIG (über 512 Zeichen).
3 Millionen Zeile mit durchschnittlich 80 Zeichen pro Zeile wird etwa 240M Bytes sein, das ist riesig für das Laden einer Datei im Speicher. –
@ Vikram.exe. Nicht wirklich. Diese Maschine verfügt über 4 GB Arbeitsspeicher. 240M ist nichts. –
@ S.Lott, yeah Ich stimme zu, es ist nichts, aber ich habe mich nur gefragt, ob wir es irgendwie (mit wenig Aufwand) tun können, ohne die ganze Datei in den Speicher zu laden. –
dauert nur wenige Sekunden in Python:
>>> import random
>>> lines = open('3mil.txt').readlines()
>>> random.shuffle(lines)
>>> open('3mil.txt', 'w').writelines(lines)
Dies funktioniert nicht. 'shuffle' funktioniert nur für relativ kleine Listen, ungefähr 2.000 Artikel oder weniger. Je nach Länge der Zeilen kann es auch keine "vernünftigen" Speicheranforderungen geben. Nun, wenn Sie nur "zufällige" Reihenfolge benötigen, ist dies vielleicht gut genug. Aber vielleicht nicht. Weitere Informationen finden Sie unter http://stackoverflow.com/questions/3062741/maximal-length-of-list-to-shuffle-with-python-random-shuffle. –
Es funktioniert sicherlich * und funktioniert gut. Dass es nur 2 ** 19937 Permutationen erzeugen kann, ist trivial, grenzt an irrelevant. Jeder RNG-basierte Shuffle hat dieselbe "Begrenzung". –
Wie ist eine 'sort()' -basierte Lösung besser als 'shuffle()'? Es vermeidet dieses vermeintliche Problem nicht. –
Auf vielen Systemen der sort
Shell-Befehl nimmt -R
seinen Eingang randomisieren.
Beachten Sie, dass die Option "-R" immer noch identische Zeilen sortiert, was möglicherweise nicht das gewünschte Verhalten ist. –
'shuf' wird Zeilen ohne Rücksicht auf Gleichheit randomisieren, und ist vielleicht die schnellste Lösung – fuzzyTew
Hier ist eine andere Version
Bei der Shell, verwenden Sie diese.
python decorate.py | sort | python undecorate.py
decorate.py
import sys
import random
for line in sys.stdin:
sys.stdout.write("{0}|{1}".format(random.random(), line))
undecorate.py
import sys
for line in sys.stdin:
_, _, data= line.partition("|")
sys.stdout.write(line)
Verwendet fast kein Gedächtnis.
Wie oben beschrieben, sortiert 'sorte -R nach einem zufälligen Schlüssel. Einfacher als Dekoration und Dekore der Datei. –
@Chris B. Wie schon oben erwähnt, wird '-R' immer noch identische Zeilen gruppieren, was nicht der Fall ist. Wenn das das gewünschte Verhalten ist, dann ist das der richtige Weg. – aaronasterling
Wie oben bereits erwähnt, wird' shuf' Zeilen zufällig setzen mit jeder Permutation gleich wahrscheinlich, und erfordert keinen benutzerdefinierten Code früh besser als das Schreiben und Debuggen Ihres eigenen Programms. –
Dies ist die gleiche wie Herr Kugelman der ist, aber die Verwendung von vim Python-Schnittstelle Built-in:
:py import vim, random as r; cb = vim.current.buffer ; l = cb[:] ; r.shuffle(l) ; cb[:] = l
Wenn Sie alles in den Speicher zu tun laden nicht wollen und es dort zu sortieren, Sie haben um die Zeilen auf der Festplatte zu speichern, während sie zufällig sortiert werden. Das wird sehr langsam sein.
Hier ist eine sehr einfache, dumme und langsame Version. Beachten Sie, dass dies eine überraschend große Menge Speicherplatz beanspruchen kann und sehr langsam ist. Ich habe es mit 300.000 Zeilen ausgeführt und es dauert einige Minuten. 3 Millionen Zeilen könnten sehr gut eine Stunde dauern. Also: Mach es in Erinnerung. Ja wirklich. Es ist nicht so groß.
import os
import tempfile
import shutil
import random
tempdir = tempfile.mkdtemp()
print tempdir
files = []
# Split the lines:
with open('/tmp/sorted.txt', 'rt') as infile:
counter = 0
for line in infile:
outfilename = os.path.join(tempdir, '%09i.txt' % counter)
with open(outfilename, 'wt') as outfile:
outfile.write(line)
counter += 1
files.append(outfilename)
with open('/tmp/random.txt', 'wt') as outfile:
while files:
index = random.randint(0, len(files) - 1)
filename = files.pop(index)
outfile.write(open(filename, 'rt').read())
shutil.rmtree(tempdir)
Eine andere Version wäre die Dateien in einer SQLite-Datenbank zu speichern und die Linien zufällig aus der Datenbank ziehen. Das wird wahrscheinlich schneller sein.
"Das wird sehr langsam sein"? Langsamer ja. Sehr langsam ist strittig. Jeder einzelne Schritt ist ziemlich schnell. –
@ S.Lott: Nun, hängt vom Dateisystem ab. Ich habe ext3 benutzt. 30.000 Artikel benötigten 5,5 Sekunden. 100.000 Artikel benötigten 16,3 Sekunden. 200.000 Artikel benötigen 339 Sekunden. Ich denke, die Verzeichnissuche wird langsam mit vielen Elementen. 3 Millionen Artikel werden * Stunden * dauern. Mindestens. Eine Datenbank könnte ziemlich schnell sein, aber ich kann mich nicht darum kümmern, sie zu testen. :-) Eine andere Möglichkeit wäre, die Datei zu lesen und einen Index für die Startposition jedes Elements zu erstellen, und seek() s. Das sollte schneller sein als das. –
Interessante Daten. Ich denke, ich habe zu lange mit sehr großen Servern verbracht. –
Ich habe gerade versucht, dies auf eine Datei mit 4,3 Millionen Zeilen und das schnellste Ding war 'Shuf' Befehl unter Linux. Verwenden Sie es so:
Es dauerte 2-3 Sekunden, um zu beenden.
Hier ist eine andere Art und Weise random.choice verwenden, dies auch entlasten einige graduelle Speicher bereitstellen kann, aber mit einer schlechteren Big-O :)
from random import choice
with open('data.txt', 'r') as r:
lines = r.readlines()
with open('shuffled_data.txt', 'w') as w:
while lines:
l = choice(lines)
lines.remove(l)
w.write(l)
"ein besseres Big-O" <- Leider nicht :-(. Das wiederholte Entfernen in 'lines.remove (l)' gibt Ihrem Algorithmus eine Laufzeit, die in der Anzahl der Zeilen quadratisch ist. Sie wird unbrauchbar sein (Laufzeit) von Stunden bis Tagen) für eine 3 Millionen Zeile Datei –
Hoppla, du hast recht :-) habe es gerade repariert –
Folgende Vimscript verwendet werden können Linien tauschen:
sehenfunction! Random()
let nswaps = 100
let firstline = 1
let lastline = 10
let i = 0
while i <= nswaps
exe "let line = system('shuf -i ".firstline."-".lastline." -n 1')[:-2]"
exe line.'d'
exe "let line = system('shuf -i ".firstline."-".lastline." -n 1')[:-2]"
exe "normal! " . line . 'Gp'
let i += 1
endwhile
endfunction
die Funktion im visuellen Modus auswählen und :@"
dann führen Sie es mit :call Random()
- 1. Aggregat nach dem Zufallsprinzip?
- 2. Nach dem Zufallsprinzip Element
- 3. Update-Skript stoppt nach dem Zufallsprinzip
- 4. Wie kann ich den Inhalt einer Datei nach dem Zufallsprinzip abtasten?
- 5. Nach dem Zufallsprinzip angezeigt Strings
- 6. Spawn Knoten nach dem Zufallsprinzip
- 7. MIPS Drucknummer nach dem Zufallsprinzip
- 8. Schreiben von Java-Dateien wird nach dem Zufallsprinzip beendet?
- 9. Paypal Payments Pro - nach dem Zufallsprinzip
- 10. SSIS 2012 Paket hängt nach dem Zufallsprinzip
- 11. Nach dem Zufallsprinzip Platz Svg Polygone
- 12. Javascript setInterval wird nach dem Zufallsprinzip gestoppt
- 13. SqlDataReader ist Tropfen Spalten nach dem Zufallsprinzip!
- 14. Laravel Sitzung läuft nach dem Zufallsprinzip
- 15. SoapUI Endpunkt Fehler nach dem Zufallsprinzip
- 16. AngularJS Körperfunktion nach dem Zufallsprinzip gehen
- 17. str.split() schlägt nach dem Zufallsprinzip fehl? zufällig
- 18. Gurke + Selen scheitert nach dem Zufallsprinzip
- 19. Reorganisieren Sie Divs nach dem Zufallsprinzip mit Javascript oder Jquery
- 20. Log4net beendet die Protokollierung nach dem Zufallsprinzip.
- 21. PHP-Schleife inkrementell nach dem Zufallsprinzip?
- 22. Einen Ball nach dem Zufallsprinzip bewegen
- 23. Gurke, Capybara & Selen funktioniert nach dem Zufallsprinzip
- 24. Nach dem Zufallsprinzip JavaScript-Array-Schlüssel
- 25. Verschiedene Knoten nach dem Zufallsprinzip erzeugen
- 26. Sequenz Js Autoplay stoppt nach dem Zufallsprinzip
- 27. Trend 100 Millionen + Zeilen
- 28. Nach dem Zufallsprinzip wählen Sie einen Artikel aus einer Liste
- 29. Selen: Behandeln Sie ein Fenster, das nach dem Zufallsprinzip auftaucht
- 30. 30 Millionen Zeilen in MySQL
Sie geben [diese Frage] (http://stackoverflow.co m/questions/1287567/c-is-using-random-and-orderby-a-good-shuffle-algorithm) für einige Ideen. –
"hat es nicht geschafft, einen einfachen Ausweg zu finden." "Ja wirklich?" Bitte poste den Code, der zu komplex wurde. –
Sollte gesagt haben, "hat es nicht geschafft, einen Ausweg zu finden". Ich bin ziemlich neu mit Python, also kenne ich nur einige Befehle. Was ich anstrebte war, alles in einen Vektor zu setzen, eine zufällige Zahl zwischen 1 und 3 Millionen zu wählen, diese Linie herauszunehmen und von vorne mit einer neuen Zufallszahl mit einer zusätzlichen Bedingung zu beginnen, die die vorherigen Zufallszahlen ausschließt. Etc. Daher meine Frage für eine einfache Art und Weise (die Sie und andere zur Verfügung gestellt). Ich werde deine akzeptieren, da du die meisten Stimmen hast. Danke an alle, aber ich habe viel gelernt! – Nigu