Lesen Sie eine kleine Stichprobe aus einer großen CSV-Datei in einen Python-Datenrahmen

Die CSV-Datei, die ich lesen möchte, passt nicht in den Hauptspeicher. Wie kann ich ein paar (~ 10K) zufällige Zeilen lesen und einige einfache Statistiken zum ausgewählten Datenrahmen machen?

6 Solutions collect form web for “Lesen Sie eine kleine Stichprobe aus einer großen CSV-Datei in einen Python-Datenrahmen”

Angenommen, kein Header in der CSV-Datei:

 import pandas import random n = 1000000 #number of records in file s = 10000 #desired sample size filename = "data.txt" skip = sorted(random.sample(xrange(n),ns)) df = pandas.read_csv(filename, skiprows=skip) 

Wäre besser, wenn read_csv hatte ein keeprows, oder wenn skiprows nahm einen Rückruf func anstelle einer Liste.

Mit Header und unbekannter Dateilänge:

 import pandas import random filename = "data.txt" n = sum(1 for line in open(filename)) - 1 #number of records in file (excludes header) s = 10000 #desired sample size skip = sorted(random.sample(xrange(1,n+1),ns)) #the 0-indexed header will not be included in the skip list df = pandas.read_csv(filename, skiprows=skip) 

Hier ist ein Algorithmus, der es nicht erfordert, die Anzahl der Zeilen in der Datei vorher zu zählen, also musst du nur einmal die Datei lesen.

Sagen Sie wollen m Proben. Zuerst hält der Algorithmus die ersten m Samples. Wenn es die i-te Probe (i> m) sieht, mit der Wahrscheinlichkeit m / i, verwendet der Algorithmus die Probe, um zufällig eine bereits ausgewählte Probe zu ersetzen.

Auf diese Weise haben wir für jeden i> m immer eine Teilmenge von m Proben, die zufällig aus den ersten i Proben ausgewählt wurden.

Siehe Code unten:

 import random n_samples = 10 samples = [] for i, line in enumerate(f): if i < n_samples: samples.append(line) elif random.random() < n_samples * 1. / (i+1): samples[random.randint(0, n_samples-1)] = line 

Das ist nicht in Pandas, aber es erreicht das gleiche Ergebnis viel schneller durch bash:

 shuf -n 100000 data/original.tsv > data/sample.tsv 

Der shuf Befehl wird die Eingabe mischen und das und das -n Argument gibt an, wie viele Zeilen wir in der Ausgabe wollen.

Relevante Frage: https://unix.stackexchange.com/q/108581

Der folgende Code liest zuerst den Header und dann ein zufälliges Sample auf den anderen Zeilen:

 import pandas as pd import numpy as np filename = 'hugedatafile.csv' nlinesfile = 10000000 nlinesrandomsample = 10000 lines2skip = np.random.choice(np.arange(1,nlinesfile+1), (nlinesfile-nlinesrandomsample), replace=False) df = pd.read_csv(filename, skiprows=lines2skip) 

Keine Pandas!

 import random from os import fstat from sys import exit f = open('/usr/share/dict/words') # Number of lines to be read lines_to_read = 100 # Minimum and maximum bytes that will be randomly skipped min_bytes_to_skip = 10000 max_bytes_to_skip = 1000000 def is_EOF(): return f.tell() >= fstat(f.fileno()).st_size # To accumulate the read lines sampled_lines = [] for n in xrange(lines_to_read): bytes_to_skip = random.randint(min_bytes_to_skip, max_bytes_to_skip) f.seek(bytes_to_skip, 1) # After skipping "bytes_to_skip" bytes, we can stop in the middle of a line # Skip current entire line f.readline() if not is_EOF(): sampled_lines.append(f.readline()) else: # Go to the begginig of the file ... f.seek(0, 0) # ... and skip lines again f.seek(bytes_to_skip, 1) # If it has reached the EOF again if is_EOF(): print "You have skipped more lines than your file has" print "Reduce the values of:" print " min_bytes_to_skip" print " max_bytes_to_skip" exit(1) else: f.readline() sampled_lines.append(f.readline()) print sampled_lines 

Sie werden am Ende mit einer sampled_lines Liste. Welche Art von Statistiken meinst du?

 class magic_checker: def __init__(self,target_count): self.target = target_count self.count = 0 def __eq__(self,x): self.count += 1 return self.count >= self.target min_target=100000 max_target = min_target*2 nlines = randint(100,1000) seek_target = randint(min_target,max_target) with open("big.csv") as f: f.seek(seek_target) f.readline() #discard this line rand_lines = list(iter(lambda:f.readline(),magic_checker(nlines))) #do something to process the lines you got returned .. perhaps just a split print rand_lines print rand_lines[0].split(",") 

So etwas sollte ich denken

  • Erstellen Sie Zufallszahl innerhalb eines Annulus
  • Schnellste Weg, um 1.000.000 + Zufallszahlen in Python zu generieren
  • Auswahl auf der Grundlage der prozentualen Gewichtung
  • Random Walk's seltsame Ergebnis in Python 3?
  • Zufällig aus der Liste mit random.randint in python wählen
  • Zufallszahlengenerator, wie man Zufallszahlen bekommt, die nicht gleich sind
  • Zurückrollen der Zufallszahlengenerator in Python?
  • Vergleich von Matlab und Numpy Code, der die Zufallsgenerierung verwendet
  • Python - gleiche Zufallszahlen erzeugen
  • N zufällige, zusammenhängende und nicht überlappende Teilsequenzen jeder Länge
  • Beste Weg, um eine Liste von Strings in Python zu randomisieren
  • Python ist die beste Programmiersprache der Welt.