In "for"-Schleife mit Arrays arbeiten

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
alex2007
User
Beiträge: 40
Registriert: Montag 14. April 2014, 10:08

Folgender umständlicher Code:

Code: Alles auswählen

from numpy import *
b=pi/3.0
a=-pi/2.0
N = int32(2.7*10**linspace(0, 4, 5))
h = (b-a) / N
summe = zeros(5)
for j in range(N[0]):    
    summe[0] += sin(a + h[0]*((2*j - 1)/2))
for j in range(N[1]):    
    summe[1] += sin(a + h[1]*((2*j - 1)/2))
for j in range(N[2]):    
    summe[2] += sin(a + h[2]*((2*j - 1)/2))
for j in range(N[3]):    
    summe[3] += sin(a + h[3]*((2*j - 1)/2))
for j in range(N[4]):    
    summe[4] += sin(a + h[4]*((2*j - 1)/2))
print summe    
Wie bekomm ich das ganze mit einer einzigen Schleife hin?

folgender Code funktioniert leider nicht, wie er soll:

Code: Alles auswählen

from numpy import *
b=pi/3.0
a=-pi/2.0
N = int32(2.7*10**linspace(0, 4, 5))
h = (b-a) / N
summe = zeros(5)
for j in range(N[i]):    
    summe[i] += sin(a + h[i]*((2*j - 1)/2))
denn hier bedeutete "range(N)" wirkliche nur einen Wertebereich, nämlich den des kompletten. Ich bräuchte hier aber etwas wie einen Befehl, der ein Array verwendet, welches quasi so aussieht [range(N[0]), range(N[1],...].

Warum brauch ich das? Nunja, ich will das ganze in eine Funktion einbetten, die am Ende einen Parameter 'anz' beinhaltet, welcher die Anzahl an Werten N und damit an Werten h festlegt. Dazu muss ich das ganze aber irgendwie anders umsetzen. Kann mir hier bitte jemand helfen?
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

@alex2007: so wie Du denkst, gar nicht, weil die for-Schleifen über verschieden lange Listen laufen. Sternchenimporte sind bei numpy ganz ganz böse, weil das viele Standardfunktionen überschreibt. Und Wenn Du schon numpy verwendest, solltest Du es auch zum Summieren benutzen.

Code: Alles auswählen

import numpy as np
b=np.pi/3.0
a=-np.pi/2.0
summe = []
for n in np.int32(2.7*10**np.linspace(0, 4, 5)):
    h = (b-a) / n
    j = np.arange(n)
    summe.append(np.sin(a + h*((2*j - 1)/2)).sum())
print summe    
alex2007
User
Beiträge: 40
Registriert: Montag 14. April 2014, 10:08

danke erstmal für die schnelle antwort.

summiert die jetzt aber auch von j=0 bis j=n? Mir war nicht ganz klar, dass es funktioniert während der Schleife ein Array zu öfnnen, welche quasi die Liste für n glieder öffnet und dann auch so oft summiert. Also benutzt er dann auch wirklichen jeden Wert j, der aus dem entsprechenden Wert n gewonnen wird?

so funktioniert das dann natürlich mit unterschiedlichen listen.

Danke für diese einfache Lösung, die Verwendung von linspace als Zählvariable und anschließende Überschreibung des Wertes in eine Liste range() innerhalb der Schleife, ist mir komplett neu und wäre mir wohl nicht sofort eingefallen.

Mein Problem im Verständnis, wie das ganze funktioniert:

Ich nehme einen Wert n, gebe j eine Liste mit range(n) und errechne dann die entsprechende summe über meine Formel. Die 'for'-Schleife ist aber nur durch die n Werte bedingt. Wiese benutzt er bei der Summierung erst alle Werte j, bevor er den nächsten Wert n verwendet und j neu überschreibt? Da hakt es im Verständnis! Kannst du mir das erklären?
BlackJack

@alex2007: Schau Dir doch einfach mal die Teilausdrücke und ihre Ergebnisse an. `j` ist keine Liste die mit `range()` erzeugt wurde, sondern ein Numpy-Array. Das verhält sich anders als Listen. Dieses Verhalten ist der Knackpunkt warum man diese Arrays benutzen möchte, weil die Schleifen dort in den Operationen ”versteckt” sind, und in der Regel in C oder Fortran direkt auf Datentypen laufen, die der Prozessor verarbeiten kann, statt Schleifen in Python-Bytecode der auf Python-Objekten operiert.

Code: Alles auswählen

In [22]: np.arange(27)
Out[22]: 
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16,
       17, 18, 19, 20, 21, 22, 23, 24, 25, 26])

In [23]: j = np.arange(27)

In [24]: 2 * j
Out[24]: 
array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
       34, 36, 38, 40, 42, 44, 46, 48, 50, 52])

In [25]: 2 * j - 1
Out[25]: 
array([-1,  1,  3,  5,  7,  9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31,
       33, 35, 37, 39, 41, 43, 45, 47, 49, 51])

In [26]: (2 * j - 1) / 2
Out[26]: 
array([-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15,
       16, 17, 18, 19, 20, 21, 22, 23, 24, 25])

In [27]: ((b - a) / 27) * (2 * j - 1) / 2
Out[27]: 
array([-0.04848137,  0.04848137,  0.1454441 ,  0.24240684,  0.33936958,
        0.43633231,  0.53329505,  0.63025779,  0.72722052,  0.82418326,
        0.92114599,  1.01810873,  1.11507147,  1.2120342 ,  1.30899694,
        1.40595968,  1.50292241,  1.59988515,  1.69684788,  1.79381062,
        1.89077336,  1.98773609,  2.08469883,  2.18166156,  2.2786243 ,
        2.37558704,  2.47254977])

In [28]: a + ((b - a) / 27) * ((2 * j - 1) / 2)
Out[28]: 
array([-1.66775906, -1.57079633, -1.47383359, -1.37687085, -1.27990812,
       -1.18294538, -1.08598265, -0.98901991, -0.89205717, -0.79509444,
       -0.6981317 , -0.60116896, -0.50420623, -0.40724349, -0.31028076,
       -0.21331802, -0.11635528, -0.01939255,  0.07757019,  0.17453293,
        0.27149566,  0.3684584 ,  0.46542113,  0.56238387,  0.65934661,
        0.75630934,  0.85327208])

In [29]: np.sin(a + ((b - a) / 27) * ((2 * j - 1) / 2))
Out[29]: 
array([-0.9953028 , -1.        , -0.9953028 , -0.98125531, -0.95798951,
       -0.92572397, -0.8847618 , -0.83548781, -0.77836491, -0.71392973,
       -0.64278761, -0.56560688, -0.4831126 , -0.39607977, -0.305326  ,
       -0.21170387, -0.11609291, -0.01939133,  0.07749242,  0.17364818,
        0.26817261,  0.36017772,  0.44879918,  0.53320443,  0.61260055,
        0.68624164,  0.7534359 ])

In [30]: np.sin(a + ((b - a) / 27) * ((2 * j - 1) / 2)).sum()
Out[30]: -7.8944469769042449
Antworten