Große 1D-Arrays: lists, Python Arrays oder numpy Arrays?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Grendel
User
Beiträge: 50
Registriert: Samstag 19. Dezember 2015, 16:06

Hallo,
ich habe mehrere, relativ große, eindimensionale Arrays mit im Intervall [1, 0] normalisierten float Werten. Was nutze ich am besten, um sie zu speichern? Sollte ich übliche Python lists verwenden, oder array.array aus der Python Lib oder doch numpy Arrays? Es handelt sich um etwa 1 Mio. Elemente pro Array. Irgendwelche Vektor- oder Matrizenoperationen finden nicht statt, sie sollten aber schnell ausgelesen und geschrieben sowie kompakt gespeichert werden können. Irgendwo las ich mal, Python-interne lists oder Arrays hätten einen Overhead aufgrund der Tatsache, dass Python alles wie ein Objekt behandelt, während numpy Arrays eher wie ein Array in C behandelt werden und damit schneller und kompakter sind. Ist das richtig?
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Schau dir mal die Nunpy-Funktionen loadtxt() und savetxt() an.
Benutzeravatar
MagBen
User
Beiträge: 799
Registriert: Freitag 6. Juni 2014, 05:56
Wohnort: Bremen
Kontaktdaten:

Grendel hat geschrieben:sie sollten aber schnell ausgelesen und geschrieben sowie kompakt gespeichert werden können.
Dann würde ich die Arrays binär abspeichern (und nicht in Text-Dateien).
Ich benutze für sowas numpy.memmap oder hdf5.
a fool with a tool is still a fool, www.magben.de, YouTube
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

korrekt ist, dass numpy mit (sehr) großen Datenmengen effizient umgehen kann und da auch performanter ist als eine Liste. Vion daher ist numpy denke ich die richtige Wahl.

Gruß, noisefloor
Grendel
User
Beiträge: 50
Registriert: Samstag 19. Dezember 2015, 16:06

Meine Frage war vielleicht etwas missverständlich ausgedrückt. Mit 'speichern' meinte ich nicht auf einer Festplatte speichern sondern lediglich im RAM, um sie dann auslesen und verarbeiten zu können.
Edit: Das Intervall ist natürlich [0, 1], das noch am Rande ...
BlackJack

@Grendel: Letztlich ist das eine Abwägung zwischen Speicherverbrauch und Geschwindigkeit, die Du am besten misst und vergleichst. Bei Arrays ist der Speicherverbrauch geringer, dafür der Zugriff auf einzelne Elemente gegebenenfalls langsamer. Was machst Du denn mit diesen Werten?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@Grendel: Du kannst das leicht selbst austesten und entscheiden, was für Deine Zwecke geeignet ist:

Code: Alles auswählen

In [1]: import random
   ...: import sys
   ...: import array
   ...: import numpy as np
   ...: 

In [2]: numbers = [random.random() for n in range(int(1e6))]

In [3]: sys.getsizeof(numbers)
Out[3]: 8697464

In [4]: numbers_ar = array.array('f', numbers)
   ...: sys.getsizeof(numbers_ar)
   ...: 
Out[4]: 4000064

In [5]: numbers_np = np.array(numbers, np.float32)
   ...: sys.getsizeof(numbers_np)
   ...: 
Out[5]: 4000096

In [6]: %timeit sum(numbers)
6.17 ms ± 44.7 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [7]: %timeit sum(numbers_ar)
10.7 ms ± 176 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

In [8]: %timeit sum(numbers_np)
162 ms ± 2.68 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

In [9]: %timeit numbers_np.sum()
430 µs ± 4.21 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
numpy bietet Dir eine hohe Geschwindigkeit, indem Du die internen Methoden nutzt. Wenn Du bei array und numpy statt float double verwendest, nehmen die Daten etwa doppelt sowie Platz ein und sind von einer Liste mit Python Float-Objekten (die intern double sind) nicht mehr weit entfernt.
BlackJack

@kbr: `getsizeof()` bei der Liste gibt nur den Wert den die Liste selbst belegt, nicht aber den Wert der Liste + den Elementen.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

@BlackJack: Danke, das hatte ich jetzt nicht bedacht. Dann ist Speicherverbrauch natürlich größer.
Grendel
User
Beiträge: 50
Registriert: Samstag 19. Dezember 2015, 16:06

BlackJack hat geschrieben: Was machst Du denn mit diesen Werten?
Unter anderem Chi-Quadrat-Tests.
BlackJack

@Grendel: Aber dann führst Du doch Rechenoperationen mit allen Elementen durch. Dein erster Beitrag klang so als würdest Du von Numpy nicht profitieren, oder höchstens beim Speicherverbrauch.
Grendel
User
Beiträge: 50
Registriert: Samstag 19. Dezember 2015, 16:06

Die Idee, dass numpy einen "fertigen" Chi-Quadrat-Test mitbringt, hatte ich noch gar nicht. :) Ich hätte das jetzt zu Fuß gemacht, weil ich dachte, numpy kann nur Vektor- und Matrizenoperationen. Kenne mich echt noch nicht mit dem Tool aus. Danke für den Wink ...
BlackJack

@Grendel: Numpy selbst hat den soweit ich weiss nicht, aber `scipy` hat da etwas: https://docs.scipy.org/doc/scipy/refere ... quare.html
Antworten