[PYTHON] Leistungsvergleich zwischen zweidimensionaler Matrixberechnung und für mit Numpy

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.

Vorwort

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.

Vergleich des Schreibens einer Liste und eines Numpy-Arrays

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.

Versuchen

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

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]

Zusammenfassung des Schreibens

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.

Vergleich der Verarbeitungsgeschwindigkeit

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

Leistungsvergleich zwischen zweidimensionaler Matrixberechnung und für mit Numpy
Unterschied zwischen Numpy 1D Array [x] und 2D Array [x, 1]
Verkettung von Matrizen mit Numpy
Unterschied zwischen Numpy- und Pandas-Methoden zur Ermittlung der Verteilung
[Python] Berechnungsmethode mit numpy
Versuchen Sie die Matrixoperation mit NumPy
Ich möchte den Unterschied zwischen der for-Anweisung in der Python + numpy-Matrix und der Julia for-Anweisung auffangen
Suche nach Zeichenketten in Dateien [Vergleich zwischen Bash und PowerShell]
Lösen mit Ruby, Python und numpy AtCoder ABC054 B Matrixberechnung
Unterschied zwischen Numpys Randint und Randoms Randint
Geschwindigkeitsvergleich zwischen CPython und PyPy
Kommunizieren Sie mit gRPC zwischen Elixir und Python
Führen Sie eine DFT-Berechnung mit ASE und GPAW durch
Selen: Warten Sie mit UND / ODER auf das Element
Lesen und Schreiben von CSV-Dateien mit Numpy
Zeichnen Sie Dreiecksfunktionen mit Numpy und Matplotlib
Vergleich der Matrixtranspositionsgeschwindigkeit durch Python
2D-Physiksimulation mit Box2d und wxPython