Werte in 2 Listen schnell addieren

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
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

Hallöle Alle,

Wie häufig sollte man an einem Tag eigentlich Hallo sagen ? :-)

Also ich habe 2 Listen, deren Werte ich index für index addieren
will zu einer neuen Liste.
Also:
a=[1,4]
b=[2,3]
a+b=[3,7]

Ich nehme an da gibt es eine schnelle Methode für ?
Ich habe mehrere 10000 Werte in mehreren Listen in einem größeren
Programm.

Grüße Markus
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

Vielleicht sollte ich an dieser Stelle aus performance Gründen einen
Code Schnippsel zeigen:

Code: Alles auswählen

        self.subplot1.bar(range(nitems),self.a_p_1.tolist(), color='red')
        self.subplot1.bar(range(nitems),self.a_p_2.tolist(), color='green',
                          bottom=self.a_p_1.tolist())
        self.subplot1.bar(range(nitems),self.a_p_3.tolist(), clor='blue',
                          bootom=self.a_p_1.tolist()+self.a_p_2.tolist())
Es werden 3 bar() Elemente in einer Grafik dargestellt. Das zweite
bar() Element fängt in y Richtung erst da an wo das erste bar() Element
aufhört. Dadurch verhindert man, dass die bar() Elemente hintereinander
liegen, d.h. ich setze die bar() Elemente aufeinander.
Das gleiche mache in mit dem dritten bar() Element, allerdings
muss ich dazu die Höhe des ersten und zweiten bar() Elementes
addieren. Da es viele Werte in meinen Array's gibt, sollte dies
möglichst effizient gelöst werden.
Meine Array sind:
self.a_p_1, self.a_p_2, self.a_p_3
Dort sind binäre Werte gespeichert.

Hat da jemand einen Tipp für mich ?

Grüße Markus
frabron
User
Beiträge: 306
Registriert: Dienstag 31. März 2009, 14:36

Zu deinem ersten Post ist mir spontan

Code: Alles auswählen

    a = (1,2)
    b = (3,4)
    for index in range(0, len(a)):
        print b[index]
eingefallen. Der zweite sagt mir jetzt grad gar nix, aber ich fange ja auch erst an mit Python ;)
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Am unkompliziertesten mit am wenigsten nachdenken geht das so:

Code: Alles auswählen

from numpy import array
a = array([1,4])
b = array([2,3])
print a + b
Wenn du mit den selben Listen mehrmals rechnen musst ist das sicherlich auch die schnellste Methode.

Oder ohne externe Abhängigkeiten:

Code: Alles auswählen

print [x + y for x, y in zip(a,b)] # bei dir ist dann vermutlich izip aus den itertools schneller
Zuletzt geändert von Darii am Mittwoch 20. Mai 2009, 08:08, insgesamt 1-mal geändert.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

frabron hat geschrieben:Zu deinem ersten Post ist mir spontan

Code: Alles auswählen

    a = (1,2)
    b = (3,4)
    for index in range(0, len(a)):
        print b[index]
eingefallen. Der zweite sagt mir jetzt grad gar nix, aber ich fange ja auch erst an mit Python ;)
Das mit der for Schleife wollte ich vermeiden, da ich viele Werte habe.

Im Prinzip will ich eine Vektoraddition, wobei meine Listen Vektoren
sind mit so vielen Komponenten, wie sie Werte haben.

Also Vektor a plus Vektor b gleich Vektor c.
Vektor a,b und c haben dabei gleich viele Werte.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Schau dir mal numpy an, das kennt Vektoren/Matrizen und die ueblichen Rechenoperationen darauf, und ich kann mir vorstellen, dass das recht gut optimiert ist.
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

Rebecca hat geschrieben:Schau dir mal numpy an, das kennt Vektoren/Matrizen und die ueblichen Rechenoperationen darauf, und ich kann mir vorstellen, dass das recht gut optimiert ist.
Ich finde die docu zu numpy nicht auf der Seite http://docs.python.org/.
Dort finde ich nur 4 Einträge zu numpy, die mir nicht sinnvoll erscheinen.

Grüße Markus
BlackJack

@feldmann_markus: Gibt es einen Grund warum Du in dem Quelltextschnippsel die `tolist()`-Methode aufrufst?

`numpy` ist auch nicht in der Standardbibliothek.
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

edit: Unsinn gelöscht :oops:

@feldmann_markus: numpy ist genau für Deine Probleme gemacht und definitiv performant! Du findest es hier:
http://www.scipy.org/Download
zusammen mit scipy - was Du Dir vielleicht auch mal anschauen solltest.

Deine Lösung, wenn mein Raten auf array.array richtig ist, ist definitiv langsam.

Gruß,
Christian
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

BlackJack hat geschrieben:@feldmann_markus: Gibt es einen Grund warum Du in dem Quelltextschnippsel die `tolist()`-Methode aufrufst?.
Ja ich benötige eine Liste für die bar() Elemente und zwar eine laaange Liste.
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

CM hat geschrieben:Deine Lösung, wenn mein Raten auf array.array richtig ist, ist definitiv langsam.
Du tippst richtig. :-)
Ich dachte allerdings array.array würde aus numpy kommen.

Kann ich mit numpy denn auch binäre Werte aus Daten laden ?
In der Docu finde ich nichts equivalentes zu,

Code: Alles auswählen

a = array.array('b')
a.fromfile(f, n)
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

Ich habe das ganze jetzt mal ein wenig optimiert mit numpy, weiß
aber nicht ob der eine oder andere einen Verbesserungs-Voschlag hat ?

hier mein Code Schnippsel:

Code: Alles auswählen

        if not hasattr(self, 'subplot1'):
            self.subplot1 = self.figure.add_subplot(211)
            self.subplot2 = self.figure.add_subplot(212)
        nitems = 1000
        self.a_p_1.fromfile(self.f_peaks_1,nitems)
        self.a_p_2.fromfile(self.f_peaks_2,nitems)
        self.a_p_3.fromfile(self.f_peaks_3,nitems)
        self.a_pv_1.fromfile(self.f_peakvalue_1,nitems*2)#real + imag part
        self.a_pv_2.fromfile(self.f_peakvalue_2,nitems*2)
        self.a_pv_3.fromfile(self.f_peakvalue_3,nitems*2)
        d = range(nitems)
        a = np_array(self.a_p_1.tolist())
        b = np_array(self.a_p_2.tolist())
        c = np_array(self.a_p_3.tolist())
        bar1 = self.subplot1.bar(d,a, color='red', align='center')
        bar2 = self.subplot1.bar(d,b, color='green', align='center',
                                 bottom=a)
        bar3 = self.subplot1.bar(d,c, color='blue', align='center',
                                 bottom=a+b)
Die array.array Methode benötige ich aber trotzdem zum laden der
Werte aus den binären Dateien.

Vielleicht hat da Jemand einen schnelleren Vorschlag ?

Grüße Markus
BlackJack

Hier hättest Du die `tolist()`-Methode jetzt nicht gebraucht, das ist nur ein unnötiger Zwischenschritt.

Aber Du solltest Dir mal `numpy.fromfile()` anschauen. Das ist echt nicht zu finden gewesen? :-)
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Was bitte ist bei Dir "binär"? numpy.fromfile() kann sehr wohl binäre Daten lesen. Wie sieht denn Deine Datei aus (Beschreibung, bitte keine wirklich binären Daten posten)? Hast Du Die Datei selber erstellt? Wie? (Vielleicht kann man da drehen, so dass es leichter / schneller zu lesen ist.) Wie ist der dtype Deiner arrays? Z.B. 'complex128'?

Vorschläge:
- ebenso wie BJ: Lass das .tolist() weg - das braucht man gaaanz selten wirklich.
- die fromfile-Aufrufe sehen seltsam aus: Brauchst Du da wirklich keine Zuweisung?
- Ich würde ja plotting und Datenbearbeitung trennen. Das sind zwei Paar Schuhe und das Leben ist einfacher, wenn man diese Dinge trennt.

HTH
Christian
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

CM hat geschrieben:Was bitte ist bei Dir "binär"?

3 meiner Dateien enthalten nur:
(bin)00000000 --> 0(dez)
ODER
(bin)00000001 --> 1(dez)
die anderen 3 dateien enthalten:
00000000 00000000 00000000 00000000 --> 32bit float Zahl(Real Anteil)
UND
00000000 00000000 00000000 00000000 --> 32bit float Zahl(Imag Anteil)
Also ein Datensatz würde in den ersten 3 Dateien 8bit haben und in den
anderen 3 Dateien 64bit haben.
CM hat geschrieben:numpy.fromfile() kann sehr wohl binäre Daten lesen. Wie sieht denn Deine Datei aus (Beschreibung, bitte keine wirklich binären Daten posten)? Hast Du Die Datei selber erstellt? Wie? (Vielleicht kann man da drehen, so dass es leichter / schneller zu lesen ist.) Wie ist der dtype Deiner arrays? Z.B. 'complex128'?

Sieh oben. Die Dateien werden von einem OpenSource Programm
namens Gnuradio erstellt. Der Source Code ist in C++. Bitte verschont
mich. :-) Es wäre möglich eigene Module für Gnuradio zu programmieren,
wenn man genügend zeit und Erfahrung hat, die die Daten anders
ablegen.
CM hat geschrieben:Vorschläge:
- ebenso wie BJ: Lass das .tolist() weg - das braucht man gaaanz selten wirklich.
- die fromfile-Aufrufe sehen seltsam aus: Brauchst Du da wirklich keine Zuweisung?
- Ich würde ja plotting und Datenbearbeitung trennen. Das sind zwei Paar Schuhe und das Leben ist einfacher, wenn man diese Dinge trennt.
Hi und danke für die Antwort,

ich habe einige Kritik Punkte von Euch geändert.

mein jetziger Code Ausschnitt sieht wie folgt aus:

Code: Alles auswählen

class GraphWindow(wx.Window):
    def __init__(self, *args, **kwargs):
        wx.Window.__init__(self, *args, **kwargs)
        self.lines = []
        self.figure = Figure()
        self.canvas = FigureCanvasWxAgg(self, -1, self.figure)
        f_p_1 = file('../../../peakdetektor1.hex','rb')
        f_p_2 = file('../../../peakdetektor2.hex','rb')
        f_p_3 = file('../../../peakdetektor3.hex','rb')
        f_pv_1 = file('../../../peakband1.hex','rb')
        f_pv_2 = file('../../../peakband2.hex','rb')
        f_pv_3 = file('../../../peakband3.hex','rb')
        nitems = 1000
        self.a_p_1 = numpy.fromfile(f_p_1,dtype='b',count=nitems)
        self.a_p_2 = numpy.fromfile(f_p_2,dtype='b',count=nitems)
        self.a_p_3 = numpy.fromfile(f_p_3,dtype='b',count=nitems)
        self.a_pv_1 = numpy.fromfile(f_p_1,dtype='f',count=nitems*2)#real + imag part
        self.a_pv_2 = numpy.fromfile(f_p_1,dtype='f',count=nitems*2)
        self.a_pv_3 = numpy.fromfile(f_p_1,dtype='f',count=nitems*2)
        self.draw(nitems)

    def draw(self,nitems):
        if not hasattr(self, 'subplot1'):
            self.subplot1 = self.figure.add_subplot(211)
            self.subplot2 = self.figure.add_subplot(212)
        d = range(nitems)
        a = self.a_p_1
        b = self.a_p_2
        c = self.a_p_3
        bar1 = self.subplot1.bar(d,a, color='red', edgecolor='red',align='center')
        bar2 = self.subplot1.bar(d,b, color='green', edgecolor='green',align='center',
                                 bottom=a)
        bar3 = self.subplot1.bar(d,c, color='blue', edgecolor='blue',align='center',
                                 bottom=a+b)
Danke für die Tipps und Antworten Grüße Markus
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hübsch ;-)

Und in einem nächsten Schritt würde ich die festen Verdrahtungen der Dateinamen lösen und einen Filedialog implementieren. Außerdem würde ich PATH so erweiteren, dass es Dein Programm erkennt. Arbeitest Du unter der bash?, dann ginge das so:

Code: Alles auswählen

export PATH=$PATH:/home/dein_user_name/rest/des/pfads
Diese Zeile in die .bashrc einstellen.

Das ist jetzt von mir ins Blaue geschossen und vielleicht Eulen nach Athen getragen, in dem Fall einfach ignorieren.

Jedenfalls könntest Du Dein Programm so in jedem Verzeichnis aufrufen - auch im Datenverzeichnis und ggf. auch die Dateien in der Kommandozeile mitgeben und über sys.argv ansprechen ...

HTH
Christian
feldmaus
User
Beiträge: 284
Registriert: Donnerstag 12. Oktober 2006, 16:48

CM hat geschrieben:Jedenfalls könntest Du Dein Programm so in jedem Verzeichnis aufrufen - auch im Datenverzeichnis und ggf. auch die Dateien in der Kommandozeile mitgeben und über sys.argv ansprechen ...
Wenn ich zeit habe, dann mache ich das nochmal. Allerdings habe ich ja
relative Pfade benutzt. Schließlich ändere ich meinen Ordner mit
den Dateien jeden Tag. :-) Aus Backup Gründen und um Korrekturen
rückgängig machen zu können.

Danke und Grüße Markus
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

feldmann_markus hat geschrieben:Schließlich ändere ich meinen Ordner mit
den Dateien jeden Tag. :-) Aus Backup Gründen und um Korrekturen
rückgängig machen zu können.
Dann solltest du besser Mercurial verwenden, statt den Ordner zu wechseln.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Wobei sich auch Git anbietet ;)
(Andere DVCS lass ich mal aussen vor, da ich nur mit den beiden Erfahrungen gemacht hab)

VCS erleichtern Projekte einfach unglaublich .. und da du ja an einem größeren arbeitest rennst du momentan ohne eines womöglich ins Verderben.
Antworten