Wie schreibt man in diesem Artikel die folgende zweidimensionale Matrixberechnung in Pythons Numpy? Das ist.
for i in range(0, ni-1):
for j in range(0, nj-1):
y[i, j] = x[i, j] + x[i+1, j] - x[i+1, j+1] * x[i, j+1]
Später werden wir die Leistung vergleichen. Die Python-Version ist 3.7.4. Ich benutze anaconda3-2019.10.
COVID-19 + Als ich meinen Job wechselte, beschloss ich, jeden Tag Freizeit zu haben und eine neue Sprache zu lernen, wenn ich in meinem Haus in Tokio feststeckte. Python scheint die Hauptsache am nächsten Arbeitsplatz zu sein, also Python. Ich muss mein Geld kürzen, um es ernst zu nehmen, also nahm ich an einem Kurs bei Udemy teil und verbrachte ungefähr eine Woche damit, die Grundlagen zu lernen. Ich habe lange programmiert, aber Python ist ein Anfänger mit ungefähr zwei Wochen Erfahrung.
Nachdem ich alle Schritte ausprobiert habe, habe ich das Gefühl, dass ich mit Python Webentwicklung betreiben kann, aber da ich Python machen werde, möchte ich Datenanalyse und maschinelles Lernen durchführen. Also habe ich die Lösung der eindimensionalen Translokationsgleichung, die ich vor langer Zeit in Python gemacht habe, neu geschrieben.
▶ 1 Dimensional Flow Calculation by Python
Ich habe die Details nicht überprüft und Ecken abgeschnitten, aber ich war mit den Ergebnissen zufrieden, die ich zum ersten Mal wollte. Aber was für ein Erfolgserlebnis? Ich konnte so etwas nicht fühlen, also habe ich eine zweidimensionale Berechnung versucht, aber die Matrixberechnung war extrem langweilig. Mein Geist flüstert, dass ich nicht mehr weiter schreiben soll. Und In Python
Es ist nur ein Gerücht. Als Lösung habe ich gehört, dass ich Numpy usw. verwenden würde, also habe ich versucht, es zu verwenden, aber es ist nur verwirrend und ich glaube nicht, dass ich es sofort lernen kann, also werde ich es als Memo hinterlassen.
Alles, was Sie durch das Lesen dieses Artikels erhalten können, ist, dass Sie nicht "Verwenden Sie numpy, um Matrizen zu berechnen (nicht verwenden für)" lesen müssen. Abgesehen davon denke ich nicht, dass es Ihnen in den Sinn kommt, selbst wenn Sie es lesen. Wenn Sie es verstehen, sollten Sie Ihre Hand tatsächlich bewegen, um es zu überprüfen und zu wiederholen, bis es in Ihre Hand passt.
Python hat `list, tuple, dict``` usw., um Arrays darzustellen, und für zweidimensionale Arrays kommt`
list aus anderen Sprachen. Es ist leicht zu verstehen, ob es sich um "x [i] [j]" usw. handelt. Aus der mathematischen Notation ist jedoch "x [i, j]" leichter zu verstehen. In dem Array von `` `numpy
wird es wie das letztere geschrieben. Wie Sie sehen können, wenn Sie es tatsächlich schreiben, ist das Schreiben von "x [i] [j]" oft ärgerlich und schwer zu sehen, so wie "x [i, j]" Ich bin dankbar, schreiben zu können.
Dann sofort. Angenommen, Sie haben die folgende Formel, die "x, y" in der Form "ndarray" berechnet.
y[i, j] = x[i, j] + x[i+1, j] - x[i+1, j+1] * x[i, j+1]
Es ist keine besonders aussagekräftige Formel, aber Sie sollten diese Art der Berechnung häufig nicht nur in numerischen Systemen, sondern auch in der Verarbeitung numerischer Berechnungen sehen. Verschachteln Sie dies in einer Schleife von `i``` und`
j```
for i in range(0, x.shape[0]-1):
for j in range(0, x.shape[1]-1):
y[i, j] = x[i, j] + x[i+1, j] - x[i+1, j+1] * x[i, j+1]
Wird sein. Sehr leicht zu verstehen. Wenn die maximale Anzahl von Unterteilungen `ni```,`
nj``` usw. ist.
for i in range(0, ni-1):
for j in range(0, nj-1):
y[i, j] = x[i, j] + x[i+1, j] - x[i+1, j+1] * x[i, j+1]
Es bedeutet.
Übrigens scheint es in Numpy klug, diese Berechnung wie folgt zu schreiben.
y[0:-1, 0:-1] = x[0:-1, 0:-1] + x[1:, 0:-1] - x[1:, 1:] * x[0:-1, 1:]
e? Was?
Wenn Sie genauer hinschauen, was ist das? Entspricht der Ausdruck dem in Scheiben geschnittenen Bereich? Ich fühle mich nicht so. Ich habe keine Lust, frei zu schreiben.
Lassen Sie uns überprüfen, ob es wirklich passt.
import numpy as np
x = np.random.randint(10, size=(100, 50))
y = np.zeros((100, 50))
for i in range(0, x.shape[0]-1):
for j in range(0, x.shape[1]-1):
y[i, j] = x[i, j] + x[i+1, j] - x[i+1, j+1] * x[i, j+1]
z = np.zeros_like(y)
z[0:-1, 0:-1] = x[0:-1, 0:-1] + x[1:, 0:-1] - x[1:, 1:] * x[0:-1, 1:]
if (z == y).all():
print('Streichhölzer')
else:
print('Falsch')
Das Ausführungsergebnis ist ... korrekt. 0 im Bereich ist nicht notwendig, aber zum besseren Verständnis. Andere
`0``` zu
ni, nj``` (x.shape [0], x.shape [1]
) `1``` zu
ni, nj``` (`` x.shape [0], x.shape [1]
`) `1``` zu
ni-1, nj-1 (`` `x.shape [0] -1, x.shape [1] -1
) `2``` zu
ni-3, nj-3 (`` x.shape [0] -3, x.shape [1] -3
)Und so weiter.
#0 bis ni, nj (x.shape[0], x.shape[1])
for i in range(0, x.shape[0]):
for j in range(x.shape[1]):
y[i, j] = x[i, j] + x[i, j]
z[0:, 0:] = x[0:, 0:] + x[0:, 0:]
#1 bis ni, nj (x.shape[0], x.shape[1])
for i in range(1, x.shape[0]):
for j in range(1, x.shape[1]):
y[i, j] = x[i, j] + x[i-1, j] - x[i-1, j-1] * x[i, j-1]
z[1:, 1:] = x[1:, 1:] + x[0:-1, 1:] - x[0:-1, 0:-1] * x[1:, 0:-1]
#1 bis ni-1, nj-1 (x.shape[0]-1, x.shape[1]-1)
for i in range(1, x.shape[0]-1):
for j in range(1, x.shape[1]-1):
y[i, j] = x[i, j] + x[i-1, j] - x[i+1, j-1] * x[i, j+1]
z[1:-1, 1:-1] = x[1:-1, 1:-1] + x[0:-2, 1:-1] - x[2:, 0:-2] * x[1:-1, 2:]
#2 bis ni-3, nj-3 (x.shape[0]-3, x.shape[1]-3)
for i in range(2, x.shape[0]-3):
for j in range(2, x.shape[1]-3):
y[i, j] = x[i, j] + x[i-1, j] - x[i+1, j-1] * x[i, j+1]
z[2:-3, 2:-3] = x[2:-3, 2:-3] + x[1:-4, 2:-3] - x[3:-2, 1:-4] * x[2:-3, 3:-2]
Hmmm, ist das so etwas?
# i,j von n bis ni-m, nj-Schleife zu m
# x[i, j], x[i-ln, j], x[i+ln, j-ln], x[i, j+ln]Und so weiter
for i in range(n, x.shape[0]-m):
for j in range(n, x.shape[1]-m):
y[i, j] = x[i, j] + x[i-ln, j] - x[i+ln, j-ln] * x[i, j+ln]
z[n:-m, n:-m] = x[n:-m, n:-m] + x[n-ln:-m-ln, n:-m] - \
x[n+ln:-m+ln, n-ln:-m-ln] * x[n:-m, n+ln:-m+ln
Viel zusammenfassende Unordnung. Es ist extrem schwer zu lesen, deshalb mache ich daraus einen Tisch.
start | end | i | i-1 | i+1 | i-ln |
---|---|---|---|---|---|
0 | ni | 0: |
- | - | - |
0 | ni-1 | 0:-1 |
- | 1: |
- |
1 | ni | 1: |
0:-1 |
- | - |
1 | ni-1 | 1:-1 |
0:-2 |
2: |
- |
n | ni-m | n:-m |
n-1:-m-1 |
n+1:-m+1 |
n-ln:-m-ln |
※ ni = x.shape[0]
Ist es richtig? Es ist schwer zu verstehen, egal wie Sie es schreiben. Als Python-Anfänger habe ich den offenen Eindruck, dass es nicht unter dem Gesichtspunkt der Wartbarkeit verwendet werden sollte. Zumindest zu diesem Zeitpunkt dachte ich es mir.
Ich habe eine Schleife erstellt und gemessen, damit sich die Berechnung 100 Millionen Mal dreht. In der ersten eindimensionalen Berechnung habe ich das Netz feiner gemacht und ungefähr 20 Millionen Mal berechnet. Es scheint also, dass es viele 100 Millionen Mal gibt, aber in der tatsächlichen Berechnung gibt es überhaupt nicht viele. Es war mühsam, die Fraktionen zusammenzubringen, also lass es so wie es ist. Das Messergebnis ist der Durchschnitt von jeweils 10 Ausführungen.
loop | for (sec) |
slice (sec) |
ave: s/f % |
max: s/f % |
min: s/f % |
median: s/f % |
---|---|---|---|---|---|---|
100,007,840 | 148.3013 | 1.3558 | 0.91% | 0.95% | 0.88% | 0.91% |
10,020,160 | 13.4111 | 0.1179 | 0.88% | 1.00% | 0.72% | 0.86% |
1,024,160 | 1.4228 | 0.0146 | 1.03% | 1.20% | 0.84% | 1.04% |
110,720 | 0.1536 | 0.0017 | 1.10% | 1.35% | 0.96% | 1.08% |
Überwältigendes Joiko! !! !! Pepe
Es ist nicht auf dem Niveau der Wartbarkeit. Eine grobe Fertigstellung bei etwa 1% bedeutet, dass eine Berechnung, die eine Stunde dauert, in 36 Sekunden abgeschlossen ist. Was ist mit einem Tag? Eine Woche lang? ?? 1 Monat? ?? ?? Aus Gründen der Lesbarkeit gibt es absolut keine Option für. Bitte schreiben Sie in die Kommentare.
Es ist jedoch eine andere Frage, ob diese Zahlenberechnung schnell ist oder nicht. Es scheint, dass Numpy in C-Sprache und Fortran implementiert ist, aber es ist schneller, Do-Loops in Fortran zu verschachteln! Ich denke, da ist so etwas. Nicht verifiziert.
das ist alles. Ich denke, es gibt etwas, das eher so gemacht werden sollte, aber sobald dies erledigt ist.
Recommended Posts