[PYTHON] NumPy-Beispielsammlung für diejenigen, die nicht gut in Mathe sind

NumPy ist ein Erweiterungsmodul für Python, das für die Durchführung wissenschaftlicher und technologischer Berechnungen nützlich ist, insbesondere für Matrix- und mehrdimensionale Array-Berechnungen.

Aber auch wenn Sie keine Mathematik verwenden, ist NumPy nützlich. Insbesondere kann es bequemer sein, ein Array von NumPy zu verwenden, anstatt mehrere Listen wie "[[1,2], [3,4], [5,6]]" zu verwenden.

Dieses Mal möchte ich die Verwendung von Arrays hauptsächlich in NumPy anhand von Beispielen vorstellen.

Einführung

NumPy ist eine Bibliothek für Mathematik, aber es gibt einige Teile von NumPy-Arrays, die unabhängig von der Mathematik bequem verwendet werden können. Viele der Beispiele im Internet sind jedoch für Leute gedacht, die sie in der Mathematik verwenden, und ich dachte, es wäre schwierig zu verstehen, wie man sie in anderen als der Mathematik verwendet.

Der Zweck dieses Artikels besteht daher darin, die Bequemlichkeit (hauptsächlich von Arrays) von NumPy vorzustellen, indem einige Verwendungen veranschaulicht werden, die wenig mit Mathematik zu tun haben.

Ich bin nicht gut in Mathematik und ich benutze es nicht, deshalb kann ich es kaum verstehen.

Natürlich hat die Programmierung nichts mit Mathematik zu tun, was nicht bedeutet, dass Sie sie überhaupt nicht verwenden. Mathematik bezieht sich hier auf die Verwendung von Programmierung, um mathematische Formeln auszudrücken, die in Matrizen und Differentialintegration verwendet werden.

Ein Teil des Inhalts enthält eine kleine mathematische Sache, aber selbst wenn Sie sie nicht verstehen, bezieht sie sich nicht auf das Hauptthema. Lesen Sie sie daher bitte, ohne sich darüber Gedanken zu machen.

Vorsichtsmaßnahmen für den Gebrauch

Die hier bereitgestellten Beispiele enthalten Hinweise zum Erlernen der Datenbearbeitung, und der bereitgestellte Code ist nicht immer effizient.

Überprüfen Sie es selbst, wenn Sie es tatsächlich im Betrieb verwenden.

Zielgruppe Leser

Python-Benutzer, die NumPy noch nie verwendet haben. Besonders für diejenigen, die nicht gut in Mathe sind und NumPy meiden, und für diejenigen, die nichts mit Mathe zu tun haben und NumPy nicht verwenden.

Ausführungsumgebung

Betriebssystem, Verarbeitungssystem usw.

Die Umgebung, in der die Operation bestätigt wurde, ist hauptsächlich diese ↓.

Ich habe nicht alle überprüft, aber ich beschäftige mich nicht speziell mit betriebssystemabhängigen. Die Ergebnisse beziehen sich hauptsächlich auf interaktive Umgebungen, aber es gibt auch Orte, an denen Jupyter Notebook verwendet wird.

Modul-Tool, das Sie verwenden

Von den folgenden ist das einzige Standardmodul "Kalender".

Modulname Ausführung Erläuterung
NumPy 1.11.1 Modul für die numerische Berechnungsbibliothek, das diesmal die Hauptrolle spielen wird
calendar (3.5.2) Standardmodul für die Arbeit mit Textkalendern
PIL 1.1.7 Bildverarbeitungsmodul
Matplotlib 1.5.1 Modul zum Zeichnen von Diagrammen Dieses Mal wird es für die Bildanzeige verwendet
Jupyter Notebook 4.2.1 REPL, die in einem Webbrowser verwendet werden kann

Grundwissen

Um das NumPy-Modul numpy zu verwenden, wird üblicherweise der Alias np verwendet. Dies gilt auch für die offizielle Referenz.

import numpy as np

Dieser Artikel folgt. Lesen Sie im Text immer als importiert, auch wenn dieser Import nicht vorhanden ist.

Das NumPy-Array hat den Typ "numpy.ndarray" (im Text im Text als "NumPy-Array" bezeichnet).

>>> np.array([1, 2])
array([1, 2])
>>> type(np.array([1, 2]))
<class 'numpy.ndarray'>

Dies sieht aus wie eine Standardliste, aber das NumPy-Array ist viel umfangreicher. In dem unten verlinkten Artikel finden Sie die Unterschiede in der Art zur Standardliste.

Grundlagen des NumPy-Arrays - Begegnung mit Python für maschinelles Lernen http://www.kamishima.net/mlmpyja/nbayes1/ndarray.html

Textkalender-Konvertierung von 1D Array nach 2D

Ein Textkalender zeigt einen Textkalender auf der Konsole an. Der Textkalender wird auch vom Befehl cal in der Unix-ähnlichen Umgebung ausgegeben.

Tatsächlich verfügt das Standard-Python-Modul über ein Modul "Kalender", das den "Textkalender" selbst verwaltet.

Kalender - Datumsverarbeitung - Python-Modul der Woche http://ja.pymotw.com/2/calendar/

Sie müssen sich also nicht die Mühe machen, es von Grund auf neu zu erstellen, aber es war ein leicht verständliches Thema als Beispiel für die Verwendung von NumPy, also habe ich es aufgegriffen.

In diesem Abschnitt werden wir uns überlegen, wie wir mit fast keinem Kalendermodul umgehen können. Ich habe "fast" geschrieben, weil Sie zum Erstellen eines Textkalenders den ersten und den letzten Tag des Monats berechnen müssen, aber es ist nicht der Zweck dieser Zeit, über diese Berechnung nachzudenken, um sie als Kalender zu finden Dies liegt daran, dass die Funktion monthrange () des Moduls `verwendet wird.

Bild verarbeiten

Kommen wir nun zum Hauptthema.

Wie Sie anhand des tatsächlichen Kalenders sehen können, ist der Textkalender zu 90% und 9 Minuten vollständig, wenn Sie geeignete Werte auf eine 2D-Tabelle mit fester Größe von 7 x 6 anwenden. Ich bin jedoch der Meinung, dass die Verarbeitung problematisch ist, wenn sie von Anfang an zweidimensional ist. Es scheint besser, die Daten in einem eindimensionalen Array zu erstellen und später in zwei Dimensionen umzuwandeln.

NumPy-Arrays verfügen über eine reshape () -Methode, mit der ein N-dimensionales Array in eine beliebige Dimension umgewandelt wird. Sie können damit ein eindimensionales Array in ein zweidimensionales Array konvertieren.

Grob gesagt ist es in Ordnung, wenn Sie gemäß dem folgenden Ablauf verarbeiten.

・ Erste leere Daten (1 Dimension)
・ 1-31 (1 Dimension)
・ Leere Daten am Ende (1 Dimension)
↓ Kombinieren
・ Erste leere Daten + 1-31 + Letzte leere Daten (1 Dimension) * Größe ist 42
↓ In 2D konvertieren(reshape)
・ Erste leere Daten + 1-31 + letzte leere Daten (2D)
↓ Konvertieren Sie jedes Element in eine Zeichenfolge
・ Kalenderdaten (2D)

Generieren Sie eindimensionale Daten

Verwenden Sie zuerst die Funktion calendar.monthrange (), um die erforderliche Nummer zu finden.

>>> import calendar
>>>
>>> w, c = calendar.monthrange(2016, 7)
>>> w #Der erste Tag des Monats
4
>>> c #Tage des Monats
31

Für den ersten Tag des Monats wird der Tag zurückgegeben, der am Montag beginnt. Das heißt, Montag ist "0" und Sonntag ist "6". Dieses Mal möchte ich einen Kalender erstellen, der am Sonntag beginnt, damit ich ihn korrigieren kann.

#(Fortsetzung)

>>> w = w + 1 if w < 6 else 0
>>> w
5

Verwenden Sie die Funktion np.zeros (), um ein Array mit gesetzten Nullen zu erstellen. Verwenden Sie zum Erstellen eines Zahlenarrays die Funktion np.arange (), die der Standardfunktion range () ähnelt.

Wenn Sie nicht "dtype" angeben, lautet der Standarddatentyp "float64".

#(Fortsetzung)

>>> np.zeros(1).dtype
dtype('float64')
>>> np.zeros(1, dtype=int).dtype
dtype('int32')
>>> np.zeros(w, dtype=int)
array([0, 0, 0, 0, 0])
>>> np.arange(start=1, stop=c+1, dtype=int)
array([ 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, 27, 28, 29, 30, 31])
>>> np.zeros(42 - w - c, dtype=int)
array([0, 0, 0, 0, 0, 0])

Sie können Arrays mit der Funktion np.concatenate () verbinden. Bitte beachten Sie, dass es sich bei der Berechnung von zwei NumPy-Arrays mit + um eine Vektor- / Matrixberechnung handelt.

#(Fortsetzung)

>>> np.array([1, 2]) + np.array([3, 4])
array([4, 6]) #Summe als Vektor
>>> headfiller = np.zeros(w, dtype=int)
>>> days = np.arange(start=1, stop=c+1, dtype=int)
>>> tailfiller = np.zeros(42 - w - c, dtype=int)
>>> np.concatenate((headfiller, days, tailfiller))
array([ 0,  0,  0,  0,  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, 27, 28, 29,
       30, 31,  0,  0,  0,  0,  0,  0])

Sie können auch zuerst 42 Nullen vorbereiten und diese mit der Reihenfolge der Tage überschreiben. Beachten Sie in diesem Fall, dass ein Fehler auftritt, wenn die Größe des zu überschreibenden Arrays und die Größe des Bereichs nicht übereinstimmen.

#(Fortsetzung)

>>> days = np.zeros(42, dtype=int)
>>> days[w:w+c] = np.arange(start=1, stop=c+1, dtype=int)
>>> days
array([ 0,  0,  0,  0,  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, 27, 28, 29,
       30, 31,  0,  0,  0,  0,  0,  0])

Wenn es einfacher ist, aus einer Standardliste zu generieren, konvertieren Sie sie später mit der Funktion np.array () in ein NumPy-Array. dtype behält den Typ der ursprünglichen Liste bei.

#(Fortsetzung)

>>> days = np.array([0] * w + list(range(1, c+1)) + [0] * (42 - w - c))
>>> days.dtype
dtype('int32')
>>> days
array([ 0,  0,  0,  0,  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, 27, 28, 29,
       30, 31,  0,  0,  0,  0,  0,  0])

Sie haben jetzt einen eindimensionalen Array-Kalender.

Konvertieren Sie ein eindimensionales Array in ein zweidimensionales Array

Konvertieren Sie dies dann in ein zweidimensionales Array. Da die Dimension in der Reihenfolge der Zeilen und Spalten angegeben wird, lautet sie "(6, 7)".

#(Fortsetzung)

>>> days.reshape((6, 7))
array([[ 0,  0,  0,  0,  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, 27, 28, 29, 30],
       [31,  0,  0,  0,  0,  0,  0]])

Konvertieren Sie danach den numerischen Wert in die Zeichenfolgendarstellung, und die Daten sind fertig.

Konvertieren Sie jedes Element in eine Zeichenfolgendarstellung

Um eine neue Liste durch Transformieren jedes Elements der Liste zu erstellen, verwenden die Standardfunktionen die Funktion map () und die Notation der Listeneinbeziehung. Verwenden Sie die Funktion np.vectorize (), um dasselbe mit einem Array von NumPy zu tun.

#(Fortsetzung)

>>> mapper = np.vectorize(lambda x: "  " if x == 0 else "%2d" % x)
>>> mapper
<numpy.lib.function_base.vectorize object at 0x0000000002D3C668>
>>> mapper(days.reshape((6, 7)))
array([['  ', '  ', '  ', '  ', '  ', ' 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', '27', '28', '29', '30'],
       ['31', '  ', '  ', '  ', '  ', '  ', '  ']],
      dtype='<U2')

Das durch vectorize erstellte Funktionsobjekt ist wie eine teilweise Anwendung der Konvertierungsfunktion auf die Funktion map (). Durch Anwenden eines Arrays auf dieses Funktionsobjekt wird ein zugeordnetes Array zurückgegeben.

Die Verarbeitungsreihenfolge dieser Zuordnung und "Umformung" kann umgekehrt werden.

Alles was Sie tun müssen, ist zu kombinieren und auszugeben. Dekorieren Sie, wie Sie möchten.

#(Fortsetzung)

>>> strdays2d = mapper(days.reshape((6, 7)))
>>> print("\n".join([" ".join(x) for x in strdays2d]))
                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 27 28 29 30
31

Abgeschlossene Version

Abschließend werde ich eine Zusammenfassung der Funktionen veröffentlichen.

import numpy as np
import calendar

def print_calendar(y, m):
    w, c = calendar.monthrange(y, m)
    w = w + 1 if w < 6 else 0
    #Version zwischen Null-Arrays
    headfiller = np.zeros(w, dtype=int)
    tailfiller = np.zeros(42 - w - c, dtype=int)
    days = np.concatenate((headfiller, np.arange(start=1, stop=c+1, dtype=int), tailfiller))
    #Die Version, die zuerst Null macht
    # days = np.zeros(42, dtype=int)
    # days[w:w+c] = np.arange(start=1, stop=c+1, dtype=int)
    #Version aus Standardliste
    # days = np.array([0] * w + list(range(1, c+1)) + [0] * (42 - w - c))
    mapper = np.vectorize(lambda x: "  " if x == 0 else "%2d" % x)
    strdays2d = mapper(days).reshape((6, 7))
    print("%d %d" % (y, m))
    print()
    print("\n".join([" ".join(x) for x in strdays2d]))

if __name__ == "__main__":
    print_calendar(2016, 8)
2016 8

    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 27
28 29 30 31

Bitmap - Generieren Sie ein Bild aus einem 2D + 1D-Array

Die Bitmap, die das Bild darstellt, besteht aus einem zweidimensionalen Array von XY-Koordinaten und Informationen, die die Farbe jedes Pixels darstellen. Lassen Sie uns dies mit einem zweidimensionalen Array von NumPy ausdrücken.

Das diesmal verwendete Modul drückt die Farben in einem Array der Größe 3 ([R, G, B]) aus, also werden wir sie kombinieren und in 3 Dimensionen ausdrücken. Abhängig von der Bibliothek kann es im Farbnamen- oder "# rrggbb" -Format angegeben werden. In diesem Fall wird es als zweidimensionales Array von "int" oder "str" ausgedrückt.

Das PIL-Modul verfügt über zahlreiche Funktionen für die Bildverarbeitung. Wenn Sie also Bilder ernsthaft verarbeiten möchten, nutzen Sie diese Funktionen bitte in vollem Umfang.

Bild mit PIL erzeugen

So generieren Sie ein Bild aus einem Array von NumPy in PIL:

import numpy as np
from PIL import Image

imgdata = np.zeros((16, 16, 3), dtype=np.uint8)
imgdata[:] = [255, 0, 0]

im = Image.fromarray(imgdata)
im.show() #Wird in Image Viewer unter Windows als BMP-Datei angezeigt
im.save("/path/to/image.png ", "PNG")

Sie können allen zweidimensionalen Elementen den gleichen Wert zuweisen, indem Sie "imgdata [:] = ..." setzen. (Der Punkt ist, dass es nicht dreidimensional ist.)

Erstellen Sie ein Bildobjekt mit der Funktion Image.fromarray (). Wenn die Methode show () ausgeführt wird, wird sie im Bildbetrachter des Betriebssystems angezeigt. Sie können das Bild in einer Datei speichern, indem Sie die Methode save () ausführen.

Wenn Sie diesen Code ausführen, wird eine 16 x 16 rot gefüllte PNG-Bilddatei generiert.

Zeichnen Sie mit Matplotlib auf Jupyter Notebook

Eine einfachere Möglichkeit ist die Verwendung von Matplotlib. Führen Sie den folgenden Code aus, um das generierte Bild direkt auf dem Jupyter-Notizbuch anzuzeigen. Die Daten sind die gleichen wie für PIL.

%matplotlib inline

import matplotlib.pyplot as plt
import numpy as np

imgdata = np.zeros((16, 16, 3), dtype=np.uint8)
imgdata[:] = [255, 0, 0]

# plt.figure(figsize = (1.75, 1.75)) #Ungefähr die tatsächliche Größe bei einer Größe von 100 x 100
# plt.axis("off") #Skala nicht anzeigen
plt.imshow(imgdata)
# plt.show() #Löschen Sie die Zeichenfolgendarstellung des Objekts

Diese Methode skaliert standardmäßig automatisch die Größe des Bildes. Da es als Grafik angezeigt wird, wird auch der Speicher angezeigt. Sie können den auskommentierten Code im Codebeispiel verwenden, um die Größe zu ändern oder nur das Bild anzuzeigen.

In den folgenden Beispielen ist diese Einstellung redundant, daher verwenden wir nur die Funktion imshow ().

matplot-red16.png

Ab diesem Zeitpunkt wird die von Jupyter Notebook ausgeführte Datei veröffentlicht. Wenn Sie Jupyter Notebook nicht verwenden, lesen Sie sie bitte als Code, der die Datei mit PIL ausgibt.

In einer Schleife verarbeiten

Hier sehen wir uns an, wie Sie das mehrdimensionale Array von NumPy durch Bitmap-Manipulation manipulieren können.

Machen wir ein 100x100 Bild. Lassen Sie dann Grün den numerischen Werten von "x" und "y" entsprechen und ändern Sie den Wert.

NumPy-Arrays können auf natürliche Weise mehrdimensionale Arrays verarbeiten, z. B. "imgdata [y, x]". Es ist zu beachten, dass der Zugriff auf ein zweidimensionales Array "[y, x]" ist, da die erste Dimension die vertikale Richtung und die zweite Dimension die horizontale Richtung bedeutet.

Im folgenden Beispiel werden Farbinformationen für jedes Element in einer Schleife festgelegt. Nur der Grünwert wird mit den Werten "x" und "y" geändert.

%matplotlib inline

from matplotlib.pyplot import imshow
import numpy as np

w, h = 100, 100 #Breite Höhe
imgdata = np.zeros((w, h, 3), dtype=np.uint8)
for x, y in [(x, y) for x in range(w) for y in range(h)]:
    imgdata[y, x] = [0, x + y, 0]

imshow(imgdata)

matplot-green-grad.png

Ich konnte eine grüne Abstufung zeichnen.

Prozess in Reichweite

Sie können auch einen Bereich angeben und dort denselben Wert festlegen. Durch Setzen von "[10:30, 50:80]" werden alle Elemente im rechteckigen Bereich mit den Eckpunkten (50, 10), (50, 30), (80, 30), (80, 10) Kann angegeben werden.

%matplotlib inline

from matplotlib.pyplot import imshow
import numpy as np

w, h = 100, 100
imgdata = np.zeros((w, h, 3), dtype=np.uint8)
imgdata[10:30, 50:80] = [0, 0, 255]

imshow(imgdata)

matplot-blue-rect.png

Variation

Sie können diese kombinieren, um Muster und Figuren zu zeichnen.

Der folgende Code ist ein Beispiel für das Zeichnen eines Bildes durch Kombination von Schleifenverarbeitung und Bereichsverarbeitung.

%matplotlib inline

from matplotlib.pyplot import imshow
import numpy as np
from math import sin, cos

w, h = 100, 100
a = np.zeros((w, h, 3), dtype=np.uint8)
for x, y in [(x, y) for x in range(w) for y in range(h)]:
    v = int(127 + sin(x * 0.6) * cos(y * 0.6) * 128)
    a[y, x] = [v, v, 0]
a[10:30, 10:70] = [int("ff", 16), int("66", 16), 0]
a[20:50, 20:80] = [int("ff", 16), int("cc", 16), 0]
a[30:70, 30:90] = [int("66", 16), int("ff", 16), 0]

imshow(a)

matplot-mix.png

Numerisch abrufende Slices (Teilarrays) wie Zeilen und Spalten

Ein Zahlenort oder ein Zahlenort ist eine Art Zahlenrätsel. Es ist ein Puzzle, das die Zahlen 1 bis 9 in der 9x9-Tabelle ausfüllt, sodass dieselben Zahlen nicht vertikal, horizontal und 3x3 eingegeben werden.

Sugoku-Wikipedia https://ja.wikipedia.org/wiki/%E6%95%B0%E7%8B%AC

Lassen Sie uns ein Programm zur Lösung von Mathematik mit dem zweidimensionalen Array von NumPy erstellen. Sie müssen keine Mathematikkenntnisse haben, da es sich hier nur um eine sehr einfache Logik handelt.

Die einfachste Logik zum Ausfüllen einer Zahl besteht darin, nach einer Zahl zu suchen, die nicht vertikal, horizontal oder 3x3 in einem Quadrat verwendet wird. Das NumPy-Array ist nützlich, um vertikale, horizontale und 3x3-Nummernlisten abzurufen. Das NumPy-Array allein kann jedoch etwas umständlich sein. Verwenden Sie es daher in Kombination mit dem Standardauflistungstyp.

Verwenden Sie das folgende zweidimensionale Array als Beispieldaten. Null zeigt eine nicht gefüllte Zelle an.

grid = np.array([
[3, 0, 0, 0, 0, 9, 0, 0, 8],
[0, 0, 0, 0, 0, 6, 7, 0, 0],
[9, 8, 2, 0, 0, 0, 6, 0, 0],
[0, 9, 0, 0, 3, 0, 4, 0, 0],
[0, 3, 5, 0, 0, 0, 2, 1, 0],
[0, 0, 7, 0, 2, 0, 0, 9, 0],
[0, 0, 4, 0, 0, 0, 9, 7, 5],
[0, 0, 9, 6, 0, 0, 0, 0, 0],
[8, 0, 0, 4, 0, 0, 0, 0, 2],
])

Nehmen Sie eine Scheibe heraus (Teilarray)

Wenn 9x9 durch eine Standard-Mehrfachliste dargestellt wird, ist es schwierig, eine Liste von Spalten oder eine Liste von 3x3 neben der Liste der Zeilen abzurufen.

Mit NumPy ist es einfach, als zweidimensionale Tabelle zu arbeiten.

Aus Gründen der Klarheit haben wir nummerierte und farbige Bilder der Probleme in Deutschland bereitgestellt.

sudoku1.png

Lassen Sie uns anhand dieses Bildes etwas über die f4-Masse herausfinden.

Extrahieren Sie die Spalte "f" (grün), die Zeile "4" (beige) und die Spalte "d4-f6" 3x3 (gelb). Da 3x3 als zweidimensionales Array herausgenommen wird, wird es mit der Methode "reshape ()" in ein eindimensionales Array konvertiert.

Das extrahierte Array wird zur Vereinfachung der Verwendung in "Liste" konvertiert.

Wie im Abschnitt über Bitmaps erwähnt, bedeutet der Zugriff auf ein zweidimensionales Array, dass die erste Dimension vertikal und die zweite Dimension horizontal ist. Bitte beachten Sie, dass es "[y, x]" ist, nicht "[x, y]".

Sie können Slices (Teilarrays) erhalten, indem Sie etwas wie grid [:, 5], grid [3 ,:], grid [3: 6, 3: 6] ausführen. Wenn Sie dieselbe Bereichsspezifikation in einem Zuweisungsausdruck verwenden, können Sie den gesamten Bereich zuweisen, wie im Abschnitt Bitmap gezeigt.

#(Fortsetzung)

>>> list(grid[:, 5]) #Spalte f: x=5 Spalten
[9, 6, 0, 0, 0, 0, 0, 0, 0]
>>> list(grid[3, :]) #Zeile 4: y=3 Reihen
[0, 9, 0, 0, 3, 0, 4, 0, 0]
>>> list(grid[3:6, 3:6].reshape(9)) # d4-f6
[0, 3, 0, 0, 0, 0, 0, 2, 0]

Aggregieren Sie die Nummernliste

Von hier aus werden wir ohne Verwendung des NumPy-Arrays verarbeiten.

Sobald Sie eine Liste mit Spalten, eine Liste mit Zeilen und eine 3x3-Liste haben, können Sie diese kombinieren und in den Typ "set" konvertieren, um eine eindeutige Liste der bereits verwendeten Zahlen zu erhalten.

#(Fortsetzung)

>>> used_nums = set(list(grid[:, 5]) + list(grid[3, :]) + list(grid[3:6, 3:6].reshape(9)))
>>> used_nums
{0, 2, 3, 4, 6, 9}

Sie brauchen keine Null, aber es ist in Ordnung, eine zu haben, also lassen Sie es so, wie es ist. Sie können Nullen mit used_nums- {0} entfernen.

Wenn Sie die bereits verwendeten Nummern aus der Nummernfolge von 1 bis 9 entfernen, erhalten Sie Kandidatennummern. Verwenden Sie die Operation - vom Typ set, um die verwendeten Zahlen zu entfernen.

#(Fortsetzung)

# range(1, 10)Ist eine Zahl von 1 bis 9
>>> unused_nums = set(range(1, 10)) - used_nums
>>> unused_nums
{8, 1, 5, 7}

Wenn es nur eine nicht verwendete Nummer gibt, wird die Nummer in diesem Quadrat bestimmt. f4 konnte im aktuellen Zustand nicht auf eins eingegrenzt werden.

Schauen wir uns auch c2 an.

#(Fortsetzung)

>>> col = list(grid[:, 2]) #Spalte c: x=2 Spalten
>>> row = list(grid[1, :]) #Zeile 2: y=1 Zeile
>>> sq = list(grid[0:3, 0:3].reshape(9)) # a1-c3
>>> col, row, sq
([0, 0, 2, 0, 5, 7, 4, 9, 0], [0, 0, 0, 0, 0, 6, 7, 0, 0], [3, 0, 0, 0, 0, 0, 9, 8, 2])
>>> used_nums = set(col + row + sq)
>>> used_nums
{0, 2, 3, 4, 5, 6, 7, 8, 9}
>>> unused_nums = set(range(1, 10)) - used_nums
>>> unused_nums
{1}

Diesmal wurde die Zahl auf nur "1" eingegrenzt. Es wurde also bestätigt, dass "1" in "c2" enthalten sein wird.

Abgeschlossene Version (Entwicklung)

Durch wiederholtes Anwenden der Logik bis zu diesem Punkt auf die nicht gefüllten Zellen ist das Programm zur Lösung der Anzahl der Deutschen vorerst abgeschlossen.

Wenn Sie jedoch nicht einmal ein Feld in einer Runde füllen können, geben Sie auf. So wie es ist, implementiert es nur die grundlegende Logik in den Grundlagen, so dass es nicht gelöst wird, es sei denn, es ist ein sehr einfaches Problem.

Ich werde den Code des fertigen Beispiels veröffentlichen.

import numpy as np

grid = np.array([
[3, 0, 0, 0, 0, 9, 0, 0, 8],
[0, 0, 0, 0, 0, 6, 7, 0, 0],
[9, 8, 2, 0, 0, 0, 6, 0, 0],
[0, 9, 0, 0, 3, 0, 4, 0, 0],
[0, 3, 5, 0, 0, 0, 2, 1, 0],
[0, 0, 7, 0, 2, 0, 0, 9, 0],
[0, 0, 4, 0, 0, 0, 9, 7, 5],
[0, 0, 9, 6, 0, 0, 0, 0, 0],
[8, 0, 0, 4, 0, 0, 0, 0, 2]])

nums = set(range(1, 10)) # 1~9
square_table = [0, 0, 0, 3, 3, 3, 6, 6, 6]

def fill(x, y):
    if (grid[y, x] != 0):
        return 0
    list1 = list(grid[:, x]) #Vertikal
    list2 = list(grid[y, :]) #Seite
    xx, yy = square_table[x], square_table[y]
    list3 = list(grid[yy:yy+3, xx:xx+3].reshape(9)) # 3x3
    used_nums = set(list1 + list2 + list3)
    unused_nums = nums - used_nums
    if len(unused_nums) == 1:
        grid[y, x] = list(unused_nums)[0]
        return 1
    else:
        return 0

if __name__ == "__main__":
    for i in range(81):
        print("loop:", i + 1)
        filled = sum([fill(x, y) for x in range(9) for y in range(9)])
        if len(grid[grid == 0]) == 0:
            print("solved!")
            break
        if filled == 0:
            print("give up...")
            break
    print(grid)

Eine kleine Ergänzung zu diesem Code.

Wobei fill = sum (...) die Listeneinschlussnotation anstelle von Schleifen verwendet. Durch "Summieren" des Aufrufergebnisses jeder "fill ()" - Funktion wird die Anzahl der in der Runde gefüllten Zellen berechnet.

grid [grid == 0] ist eine der nützlichen Funktionen des NumPy-Arrays, und Sie können alle Elemente abrufen, die den Bedingungen entsprechen. Hier wird grid == 0 gesetzt, sodass alle Nullelemente extrahiert werden. Wenn Sie die Anzahl dieser Elemente zählen, können Sie die Anzahl der nicht gefüllten Zellen sehen. Ich verwende dies, um zu überprüfen, ob das Problem behoben wurde.

Wir verwenden die Umrechnungstabelle square_table, um den 3x3-Bereich zu berechnen. Sie können es mit vier Regeln tun, aber ich denke, das ist in diesem Fall klarer.

loop: 1
loop: 2
loop: 3
loop: 4
give up...
[[3 0 6 0 0 9 5 0 8]
 [0 0 1 0 0 6 7 0 0]
 [9 8 2 0 0 0 6 0 0]
 [0 9 8 0 3 0 4 5 0]
 [0 3 5 0 0 0 2 1 0]
 [0 0 7 0 2 0 0 9 0]
 [0 0 4 0 0 0 9 7 5]
 [0 0 9 6 0 0 0 0 0]
 [8 0 3 4 0 0 1 6 2]]

Das erste Problem, das ich erwähnte, konnte mit dieser Logik allein nicht gelöst werden. Wenn Sie interessiert sind, versuchen Sie bitte, Logik hinzuzufügen oder zu ändern, damit Sie fortgeschrittenere Probleme lösen können.

Das erste auf Wikipedia veröffentlichte Beispiel könnte übrigens allein durch diese Logik gelöst werden.

abschließend

Auf diese Weise können Sie je nach Prozess viel flexibler arbeiten als mit der Standardliste. Es gibt viele andere Funktionen in NumPy, aber die hier aufgeführten sollten sehr nützlich sein.

Egal, ob Sie neu in der Mathematik sind oder NumPy noch nicht verwendet haben, nutzen Sie NumPy.

Referenzmaterial

Overview — NumPy v1.11 Manual http://docs.scipy.org/doc/numpy/index.html

100 numpy exercises http://www.labri.fr/perso/nrougier/teaching/numpy.100/

python - How do I convert a numpy array to (and display) an image? - Stack Overflow http://stackoverflow.com/questions/2659312/how-do-i-convert-a-numpy-array-to-and-display-an-image

Recommended Posts

NumPy-Beispielsammlung für diejenigen, die nicht gut in Mathe sind
Java SE8 Gold misst (für diejenigen, die nicht gut darin sind)
Ansible, ein Tool zur Automatisierung der Infrastruktur für Leute, die Ruby nicht gut können
Entwickelte eine einfache Tabellenberechnungs-App für Leute, die nicht gut in Excel sind
[YOLO v5] Objekterkennung für maskierte und nicht maskierte Personen
Verfahren zur Erstellung der Umgebung für diejenigen, die mit dem Python-Versionsverwaltungssystem nicht vertraut sind
Erklärung für diejenigen, die Probleme mit "Befehl nicht gefunden" in rbenv oder pyenv haben
Bildgebende Inspektionsmaschine für diejenigen, die nicht ihr Bestes geben
Für diejenigen, die in der Atmosphäre analysieren (lineares Regressionsmodell 1)