Parsen eines NumPy Array *Hilfe*

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
qubo5000
User
Beiträge: 5
Registriert: Freitag 28. Oktober 2022, 12:16

Hallo zusammen,

ich benötige dringend Hilfe beim parsen eines numpy arrays.

Beispiel array:
array([
[0,1,0,0,0,0],
[0,0,1,0,0,0]
[0,0,0,1,0,0]
[1,0,0,0,0,0]
[0,0,0,0,01]
[0,0,0,0,1,0]]

Erste Zeile bedeutet A, zweite zeile B und so weiter...
Sprich bei diesem Beispiel wäre jetzt die Lösung die ich haben möchte:
-> D,A,B,C,F,E

Könnt ihr mir hierbei helfen, stehe komplett auf dem Schlauch und benötige es zu morgen.
Vielen Dank schonmal im Voraus :)
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

So wie Du das beschrieben hast, meinst Du aber Spalten, nicht Zeilen. Ist immer garantiert, dass pro Spalte exakt eine 1 steht?
Wo hast Du denn konkret ein Problem? Wie würdest Du eine Lösung mit eigenen Worten beschreiben?
qubo5000
User
Beiträge: 5
Registriert: Freitag 28. Oktober 2022, 12:16

Stimmt ich meine Spalten nicht Zeilen, und pro Zeile steht immer eine 1 da.
Ich dachte mir vielleicht, das man mit einer for schleife abfragen kann: ist in dieser Zeile eine 1, wenn ja an welcher Stelle befindet sich diese 1 von Anzahl N, dann packe den Buchstaben für diese Stelle in der Zeile in ein neues array in form des Buchstabens. also bei [0,1,0,0,0,0] -> in das neue array [x1,B,x3,x4,x5,x6]

Am Ende ist es eine Routenplanung, welche Standorte (bezeichnet mit den Buchstaben) werden in welcher Reihenfolge abgefahren.

Ich hoffe das hilft beim Verständnis.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Vom Vorgehen her richtig. Statt der for-Schleife kann man aber auch einfach numpy.argmax verwenden.
qubo5000
User
Beiträge: 5
Registriert: Freitag 28. Oktober 2022, 12:16

Ah okay vielen dank, könntest du mir ein Beispiel Code zur verfügung stellen? Bei der praktischen Umsetzung hapert es gerade bei mir.
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was hast du denn probiert? Denn Hausaufgaben frei Haus gibts hier eher selten.
qubo5000
User
Beiträge: 5
Registriert: Freitag 28. Oktober 2022, 12:16

Das habe ich aktuell probiert:

newarray = solution.argmax(axis=1)
newarray

Output: array([1, 2, 3, 0, 5, 4])
Das ist schonmal ziemlich cool, danke an @Sirius3 für den Tipp

newarray = solution.argmax(axis=1)
for i in newarray:
if (newarray == 0):
print("A")
elif (newarray == 1):
print("B")
elif (newarray == 2):
print("C")
elif (newarray == 3):
print("D")
elif (newarray == 4):
print("E")
elif (newarray == 5):
print("F")

Output: CDABEF

Leider ist der Output noch falsch.
Richtiger Output sollte DABCFE sein.
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das argmax liefert ja nun erstmal nur den größten Vektor. Wenn der also ausgeben wurde, muss das Ganze wiederholt werden, *ohne* das der wieder berücksichtigt wird. Also zb indem man den auf 0 setzt, und das Ganze wiederholt.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Schon wieder die Frage, ob Du Spalten oder Zeilen anschaust.
Der gezeigte Code führt übrigens zu einer Fehlermeldung und nicht zum angeblichen Output.

@__deets__: daher ja meine Frage, ob es nur eine 1 pro Spalte geben kann.
Benutzeravatar
__blackjack__
User
Beiträge: 13110
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Man kann das Ergebnis mit der passenden Methode auch in *einem* Ausdruck ermitteln. 😎 (Und der ist gar nicht mal so kryptisch.)
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
qubo5000
User
Beiträge: 5
Registriert: Freitag 28. Oktober 2022, 12:16

@Sirius3
Es kann nur eine 1 pro Spalte und Zeile geben.


@__blackjack__
von welcher Methode sprichst du ?
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

__blackjack__ wollte Dir den Hinweis geben, dass es eine praktische Metode gibt, sich das Suchen in der Doku also lohnt. Mittels packbits, einem structured array sowie sort hatte ich zwei Zeilen gebraucht, weil ich nicht alles in eine Zeile quetschen wollte. Nun verwende ich numpy eher selten – daher geht es vielleicht auch einfacher.
Benutzeravatar
__blackjack__
User
Beiträge: 13110
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Hm, `packbits()`, damit habe ich es auch hinbekommen. Aber ohne „structured array“ und Sortieren. Spannend. Es gibt also schon mal mindestens drei Wege. 🤔
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13110
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Meine Lösung wäre die Koordinaten der „nicht-nullen“ zu ermitteln, und da den ASCII-Wert von "A" auf den interessanten Teil zu addieren um an die gesuchten Buchstaben zu kommen:

Code: Alles auswählen

#!/usr/bin/env python3
import numpy as np


def main():
    data = np.array(
        [
            [0, 1, 0, 0, 0, 0],
            [0, 0, 1, 0, 0, 0],
            [0, 0, 0, 1, 0, 0],
            [1, 0, 0, 0, 0, 0],
            [0, 0, 0, 0, 0, 1],
            [0, 0, 0, 0, 1, 0],
        ]
    )
    if not all((data.sum(axis) == 1).all() for axis in [0, 1]):
        raise ValueError("data doesn't conform to one 1 per row/column")

    print(",".join(map(chr, data.transpose().nonzero()[1] + ord("A"))))


if __name__ == "__main__":
    main()
Nach dem Hinweis auf `packbits()` wäre eine Alternative:

Code: Alles auswählen

    print(
        ",".join(
            map(
                chr,
                np.log2(np.packbits(data, 0, "little"))[0].astype(np.uint8)
                + ord("A"),
            )
        )
    )
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Meine Lösung sah so aus:

Code: Alles auswählen

mapping = np.array(list("ABCDEF"))
print(",".join(mapping[data.argmax(axis=0)]))
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

Eine fortgeschrittene Auswahl für das Mapping ist eine elegante Lösung – so braucht es keine andere Datenstruktur. Letzteres war mein Ansatz – eine neue Datenstruktur anzulegen, die sich zur Sortierung mit sort() eignet:

Code: Alles auswählen

a = np.array([
[0,1,0,0,0,0],
[0,0,1,0,0,0],
[0,0,0,1,0,0],
[1,0,0,0,0,0],
[0,0,0,0,0,1],
[0,0,0,0,1,0]])
labels = "ABCDEF"

c = np.array(list(zip(np.packbits(a, axis=-1).flatten(), labels)), dtype=[('num', np.uint8), ('label', '<U1')])
print(','.join(np.sort(c)[::-1]['label']))
Antworten