2017-02-01 3 views
0

Ich habe mehrere CSV-Dateien mit 10 Millionen + Werten in ihnen, jeder Wert ist 9 Zeichen lang. Mein Ziel ist es, jede Datei in zwei gleich große Dateien zu unterteilen, wobei jede Hälfte eine zufällige Auswahl der Werte aus der ursprünglichen Menge ist.Wie man große Datenmengen zufällig in zwei gleich große Datensätze trennt

Ich denke darüber nach, dies mit PHP zu tun (weil ich ein wenig damit vertraut bin).

Ich kann mir zwei mögliche Wege vorstellen, aber neugierig auf (1) welche wird schneller laufen? (2) Gibt es eine andere Art zu tun, die besser ist? (3) oder mit einem Datensatz von etwa 10 bis 15 Millionen spielt es keine Rolle?

Plan 1:

  1. Convert CSV in ein Array
  2. Mische das Array mit den shuffle() Funktion
  3. Dividieren der Array in 2 mit dem array_chunk() Funktion
  4. Speichern jedes Array in eine CSV-Datei (nicht sicher, wie aber wird es herauszufinden)

Plan 2:

  1. Convert CSV in ein Array
  2. Verwendung array_rand(), um zufällig X Menge von Werten auswählen, wobei X = (Anzahl der Werte/2), und
  3. Wiederholen Sie Schritt 2 für die zweite aus dieser Auswahl Array erstellen die Hälfte der Werte
  4. Speicher jedes des neuen Arrays CSV

Ist das irgendwo in der Nähe richtige Datei? Soll ich eine andere Sprache betrachten?

Vielen Dank! 3

+1

Wenn die Dateien so groß sind, vergessen Sie die Verwendung von Arrays (zu hoher Speicherbedarf) .... Erstellen Sie eine temporäre Datenbanktabelle, laden Sie die Daten in diese und behandeln Sie alle Randomisierung durch die Datenbank vor dem Schreiben in Datei –

+0

Server haben den Speicher, um 90 Millionen Zeichen in einem Array zu speichern? –

+0

schnellste/einfachste Weg ist über Linux-Shell-Befehle 'wc -l-Datei', um # von Zeilen und 'split -l X-Datei' zu erhalten, wobei X ist ~ Hälfte, was der WC-Befehl gab Ihnen. Viele "Split" -Beispiele, wie dieses ... http://www.howtogeek.com/howto/ubuntu/split-a-text-file-in-half-o-anyany-percentage-on-ubuntu- linux/ –

Antwort

-1

-Plan:

1) Schreiben Sie ein PHP-Skript, das alle CSV-Daten und fügen Sie ihn in eine MySQL-Datenbank (viel exmples holt).

2) in Ihrem PHP select * from table where type = 1 order by rand() limit 10 oder eine anderen ausgefallenen Abfrage mit Zeit was auch immer

Dies ist, wie ich es tun würde.

EDIT mit Beispiel

<?php 

$files = glob("path/to/files/*.csv"); 

foreach($files as $file) { 

    if (($handle = fopen($file, "r")) !== FALSE) { 
     echo "<b>Filename: " . basename($file) . "</b><br><br>"; 
     while (($data = fgetcsv($handle, 4096, ",")) !== FALSE) { 
      //do something with the data 
      echo implode("\t", $data); 
     } 
     echo "<br>"; 
     fclose($handle); 
    } else { 
     echo "Could not open file: " . $file; 
    } 
} 

?> 

Dadurch wird der Inhalt aller CSV-Dateien in einem Verzeichnis. Denken Sie daran, dies ist eine stressige Aufgabe für einen Server mit so vielen Werten. Also vielleicht hilft das:

function listdirfile_by_date($path) 
{ 
$dir = opendir($path); 
$list = array(); 
while($file = readdir($dir)) 
{ 
    if($file != '..' && $file != '.') 
    { 
     $mtime = filemtime($path . $file) . ',' . $file; 
     $list[$mtime] = $file; 
    } 
} 
closedir($dir); 
krsort($list); 

foreach($list as $key => $value) 
{ 
    return $list[$key]; 
} 
return ''; 
} 

Eine gestohlene Funktion, die die Dateien sortiert nach Datum auflistet. Mit diesen Daten können Sie das Skript nur mit der neuesten Datei ausführen.

+0

Ich würde upvote, aber es ist ziemlich schwach als Antwort. Würde mehr Vollständigkeit schätzen ... –

+0

Yeah, hinzufügen mehr Abhängigkeiten und Technologie wird sehr wahrscheinlich bessere Lösungen, und es wird auch blitzschnell sein. Vor allem für etwas, das wie eine einmalige Operation aussieht. – Sven

Verwandte Themen