Bedingte und zeilenweise Veränderung von numpy-Matrizen

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
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Hallo.

Ich habe da ein kleines numpy-Problem, welches sich bestimmt elegant lösen lässt. Nur leider sehe ich nicht wie. Das Problem ist ganz einfach: Ich habe eine nxn-Matrix und jedes Element kann den Wert 0 oder 1 annehmen, also eine ganz normale Adjazenzmatrix. Nun würde ich gerne, abhängig von der Anzahl der Elemente in einer Zeile, die Zeilen verändern. Enthält eine Zeile keine 1, soll sollen alle Elemente der Zeile auf einen konstanten Wert 1.0/n gesetzt werden. Andernfalls sollen alle Elemente der Zeile durch die Anzahl der Elemente der Zeile dividiert werden. Am Ende ergibt das dann eine (transponierte) stoachastische Matrix.

Der offensichtliche Ansatz ist natürlich eine Schleife über die Zeilen:

Code: Alles auswählen

cnt = count_rows(m)
    
for index, (c, row) in enumerate(itertools.izip(cnt, m)):
    if c:
        row /= c
    else:
        row[:] = t
"cnt" ist ein numpy-array mit n Einträgen, jeder Eintrag gibt die Anzahl der Elemente pro Zeile an. cnt[0] die Anzahl der Elemente in der ersten Zeile, cnt[1] der zweiten, etc.

Natürlich lässt sich das ganze Problem umschiffen, indem mit ``np.vstack`` (oder ohne) und einem Generatorausdruck einfach eine neue Matrix konstruiert, mir geht es jetzt aber eher ums Prinzip :roll: Gibt es zum zeilenweisen Verändern der Matrix einen schönen Einzeiler nur mittels numpy?

Sebastian
Das Leben ist wie ein Tennisball.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@EyDu: wie wär's mit

Code: Alles auswählen

cnt = m.sum(1).reshape(-1,1)
m /= cnt
m[(cnt==0).nonzero()[0], :] = t
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Danke, das sieht schon deutlich besser aus als mein Ansatz.
Das Leben ist wie ein Tennisball.
Antworten