Ich suche nach der schnellsten Python-Bibliothek, um eine CSV-Datei (wenn das wichtig ist, 1 oder 3 Spalten, alle Ganzzahlen oder Floats, Beispiel ) in ein Python-Array (oder ein Objekt, auf das ich auf ähnliche Weise zugreifen kann, mit einem ähnlichen Zugriffszeit). Es sollte kostenlos sein, unter Windows 7 und Ubuntu 12.04 sowie mit Python 2.7 x64 funktionieren.
CSV mit 1 Spalte:
350
750
252
138
125
125
125
112
95
196
105
101
101
101
102
101
101
102
202
104
CSV mit 3 Spalten:
9,52,1
52,91,0
91,135,0
135,174,0
174,218,0
218,260,0
260,301,0
301,341,0
341,383,0
383,423,0
423,466,0
466,503,0
503,547,0
547,583,0
583,629,0
629,667,0
667,713,0
713,754,0
754,796,0
796,839,1
Also schrieb ich schließlich einen kleinen Benchmark unter Verwendung der Bibliotheken, auf die Steve Barnes hingewiesen hatte. Ich hatte das Gleiche gefunden, als ich danach gesucht hatte, als ich die Frage schrieb, also denke ich, dass dies die wichtigsten sind. Einige andere Ideen, die noch nicht ausprobiert wurden: HDF5 für Python , PyTables , IOPro (nicht kostenlos).
Kurz gesagt, pandas.io.parsers.read_csv
schlägt alle anderen, NumPy loadtxt
ist beeindruckend langsam und NumPy ist from_file
beeindruckend load
schnell.
Daten (ich hätte sie im Benchmark generieren sollen, aber mir läuft gerade die Zeit davon)
Code:
import csv
import os
import cProfile
import time
import numpy
import pandas
import warnings
# Make sure those files in the same folder as benchmark_python.py
# As the name indicates:
# - '1col.csv' is a CSV file with 1 column
# - '3col.csv' is a CSV file with 3 column
filename1 = '1col.csv'
filename3 = '3col.csv'
csv_delimiter = ' '
debug = False
def open_with_python_csv(filename):
'''
https://docs.python.org/2/library/csv.html
'''
data =[]
with open(filename, 'rb') as csvfile:
csvreader = csv.reader(csvfile, delimiter=csv_delimiter, quotechar='|')
for row in csvreader:
data.append(row)
return data
def open_with_python_csv_cast_as_float(filename):
'''
https://docs.python.org/2/library/csv.html
'''
data =[]
with open(filename, 'rb') as csvfile:
csvreader = csv.reader(csvfile, delimiter=csv_delimiter, quotechar='|')
for row in csvreader:
data.append(map(float, row))
return data
def open_with_python_csv_list(filename):
'''
https://docs.python.org/2/library/csv.html
'''
data =[]
with open(filename, 'rb') as csvfile:
csvreader = csv.reader(csvfile, delimiter=csv_delimiter, quotechar='|')
data = list(csvreader)
return data
def open_with_numpy_loadtxt(filename):
'''
http://stackoverflow.com/questions/4315506/load-csv-into-2d-matrix-with-numpy-for-plotting
'''
data = numpy.loadtxt(open(filename,'rb'),delimiter=csv_delimiter,skiprows=0)
return data
def open_with_pandas_read_csv(filename):
df = pandas.read_csv(filename, sep=csv_delimiter)
data = df.values
return data
def benchmark(function_name):
start_time = time.clock()
data = function_name(filename1)
if debug: print data[0]
data = function_name(filename3)
if debug: print data[0]
print function_name.__name__ + ': ' + str(time.clock() - start_time), "seconds"
def benchmark_numpy_fromfile():
'''
http://docs.scipy.org/doc/numpy/reference/generated/numpy.fromfile.html
Do not rely on the combination of tofile and fromfile for data storage,
as the binary files generated are are not platform independent.
In particular, no byte-order or data-type information is saved.
Data can be stored in the platform independent .npy format using
save and load instead.
Note that fromfile will create a one-dimensional array containing your data,
so you might need to reshape it afterward.
'''
#ignore the 'tmpnam is a potential security risk to your program' warning
with warnings.catch_warnings():
warnings.simplefilter('ignore', RuntimeWarning)
fname1 = os.tmpnam()
fname3 = os.tmpnam()
data = open_with_numpy_loadtxt(filename1)
if debug: print data[0]
data.tofile(fname1)
data = open_with_numpy_loadtxt(filename3)
if debug: print data[0]
data.tofile(fname3)
if debug: print data.shape
fname3shape = data.shape
start_time = time.clock()
data = numpy.fromfile(fname1, dtype=numpy.float64) # you might need to switch to float32. List of types: http://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html
if debug: print len(data), data[0], data.shape
data = numpy.fromfile(fname3, dtype=numpy.float64)
data = data.reshape(fname3shape)
if debug: print len(data), data[0], data.shape
print 'Numpy fromfile: ' + str(time.clock() - start_time), "seconds"
def benchmark_numpy_save_load():
'''
http://docs.scipy.org/doc/numpy/reference/generated/numpy.fromfile.html
Do not rely on the combination of tofile and fromfile for data storage,
as the binary files generated are are not platform independent.
In particular, no byte-order or data-type information is saved.
Data can be stored in the platform independent .npy format using
save and load instead.
Note that fromfile will create a one-dimensional array containing your data,
so you might need to reshape it afterward.
'''
#ignore the 'tmpnam is a potential security risk to your program' warning
with warnings.catch_warnings():
warnings.simplefilter('ignore', RuntimeWarning)
fname1 = os.tmpnam()
fname3 = os.tmpnam()
data = open_with_numpy_loadtxt(filename1)
if debug: print data[0]
numpy.save(fname1, data)
data = open_with_numpy_loadtxt(filename3)
if debug: print data[0]
numpy.save(fname3, data)
if debug: print data.shape
fname3shape = data.shape
start_time = time.clock()
data = numpy.load(fname1 + '.npy')
if debug: print len(data), data[0], data.shape
data = numpy.load(fname3 + '.npy')
#data = data.reshape(fname3shape)
if debug: print len(data), data[0], data.shape
print 'Numpy load: ' + str(time.clock() - start_time), "seconds"
def main():
number_of_runs = 20
results = []
benchmark_functions = ['benchmark(open_with_python_csv)',
'benchmark(open_with_python_csv_list)',
'benchmark(open_with_python_csv_cast_as_float)',
'benchmark(open_with_numpy_loadtxt)',
'benchmark(open_with_pandas_read_csv)',
'benchmark_numpy_fromfile()',
'benchmark_numpy_save_load()']
# Compute benchmark
for run_number in range(number_of_runs):
run_results = []
for benchmark_function in benchmark_functions:
run_results.append(eval(benchmark_function))
results.append(run_results)
# Display benchmark's results
print results
results = numpy.array(results)
numpy.set_printoptions(precision=10) # http://stackoverflow.com/questions/2891790/pretty-printing-of-numpy-array
numpy.set_printoptions(suppress=True) # suppress suppresses the use of scientific notation for small numbers:
print numpy.mean(results, axis=0)
print numpy.std(results, axis=0)
#Another library, but not free: https://store.continuum.io/cshop/iopro/
if __name__ == "__main__":
#cProfile.run('main()') # if you want to do some profiling
main()
Ausgabe:
open_with_python_csv: 1.57318865672 seconds
open_with_python_csv_list: 1.35567931732 seconds
open_with_python_csv_cast_as_float: 3.0801260484 seconds
open_with_numpy_loadtxt: 14.4942111801 seconds
open_with_pandas_read_csv: 0.371965476805 seconds
Numpy fromfile: 0.0130216095713 seconds
Numpy load: 0.0245501650124 seconds
So installieren Sie alle Bibliotheken: Inoffizielle Windows-Binärdateien für Python-Erweiterungspakete
Windows-Konfiguration:
import numpy; numpy.version.version
)import pandas as pd; pd.__version__
)Ausgabe:
open_with_python_csv: 1.93 seconds
open_with_python_csv_list: 1.52 seconds
open_with_python_csv_cast_as_float: 3.19 seconds
open_with_numpy_loadtxt: 7.47 seconds
open_with_pandas_read_csv: 0.35 seconds
Numpy fromfile: 0.01 seconds
Numpy load: 0.02 seconds
So installieren Sie alle Bibliotheken:
sudo apt-get install python-pip
sudo pip install numpy
sudo pip install pandas
Wenn Bibliotheken bereits installiert sind, aber aktualisiert werden müssen:
sudo apt-get install python-pip
sudo pip install numpy --upgrade
sudo pip install pandas --upgrade
Ubuntu-Konfiguration:
import numpy; numpy.version.version
)import pandas as pd; pd.__version__
)Fühlen Sie sich natürlich frei, den Benchmark zu verbessern, indem Sie kommentieren/bearbeiten/etc. Ich bin mir sicher, dass es viele Dinge zu verbessern gibt:
numpy.loadtxt
np.fromfile
scheint Ihr furchtbar schnell. Was ich in meinen Tests festgestellt habe, ist, dass es nur in der ersten Zeile funktioniert. Um die gesamte Datei zu bearbeiten, müssen Sie also eine Schleife ausführen, die die Dinge für meine CSV-Datei mit 20.000 Zeilen wieder auf 60 Sekunden verlangsamt, gegenüber 0,75 Sekunden für Pandas. Lesen Sie die gesamte Datei mit np.fromfile
? Ich konnte es auch verwenden, np.fromstring
indem ich die gesamte csv-Datei geladen habe, replace
die dann '\n
mit ''
ausgeführt wird np.fromstring
. Die String-Manipulationen waren schnell, aber die Konvertierung in Zahlen war langsam. Diese Methode dauerte 2,6 Sekunden.Ich möchte hier eine andere Bibliothek beitragen, über die ich bei der Suche nach ähnlichen Fragen gestolpert bin. Ich habe es mit Franck Dernoncourts Benchmark-Code getestet und es schlägt Pythons Standard-CSV und Pandas um Meilen. Ich konnte nicht mit numpy testen, da ich mit einer 24.000-Zeilen-CSV mit Zahlen- und Zeichenfolgenwerten getestet habe.
Diese schnelle Bibliothek basiert tatsächlich auf der Standard-csv-Implementierung und verwendet nur TextIO , wodurch sie schneller wird UND Unicode-Strings korrekt verarbeitet.
Es heißt fastcsv und wurde von Masaya Suzuki entwickelt. Sie können es in GitHub schließen oder Pypi zum Installieren verwenden. Am einfachsten ist:
pip install fastcsv
Auf http://pythonhosted.org/fastcsv/ können Sie mehr Benchmark-Ergebnisse sehen, aber um nur CSV zu lesen, lassen Sie mich ihre Ergebnisse hier wiederholen:
Wäre interessant zu wissen, wie sich das mit Ihren Daten verhält.
Sie haben eine große Auswahl, abhängig von der Datengröße und -komplexität und was Sie mit den resultierenden Daten tun werden:
csv
Bibliothek, die standardmäßig mit Python geliefert wird.numpy.from_file
Funktion - Liest in ein NumPy-Array und ist daher sehr leistungsfähig.pandas.io.parsers.read_csv
Funktion - liest in einen Pandas-Datenrahmen, ist sehr leistungsfähig und kann riesige Datensätze verarbeiten.Der erste wird wahrscheinlich schneller zu importieren sein, während die anderen leistungsfähiger sind. Alle sind kostenlos und plattformübergreifend. Die erste ist bereits Teil Ihrer Python-Installation, wenn Sie eine Standardinstallation haben.
Es gibt ein neues pydatatable
Paket mit einem sehr schnellen CSV-Reader, der auf der Implementierung von R data.table basiert fread
.
Lesen Sie mehr unter https://github.com/h2oai/datatable Wenn Sie das Pandas-Objekt laden möchten, können Sie es einfach ausführen
pandas_dataframe = dt.fread(srcfile).to_pandas()
Ich würde vorschlagen, die offizielle Dokumentation von Pandas zu IO im Auge zu behalten . Die Wahlmöglichkeiten ändern sich je nach Entwicklungszyklus und ständig kommen neue Formate hinzu. Sie veröffentlichen auch den Benchmark.
Es gibt ein neues Python-Paket für Data Mining mit dem Namen DaPy . Welches eine einfache E/A-API hat und schnell genug für Sie ist. Laut dem Leistungstest des Autors benötigte DaPy 12,5 Sekunden zum Laden einer CSV-Datei mit mehr als 2 Millionen Datensätzen, während Pandas 4 Sekunden brauchten. DaPy basiert jedoch auf einigen Python-nativen Datenstrukturen und ist einfacher zu verwenden.
cmd: pip install DaPy
>>> import DaPy as dp
>>> data = dp.read('file.csv')
>>> data.show()
ComFreek
Hexerei-Software