Direkter Weg, um die Summe aller parallelen Diagonalen in Numpy / Pandas zu generieren?

8

Ich habe einen rechteckigen (kann nicht als quadratisch angenommen werden) Pandas DataFrame von Zahlen. Angenommen, ich wähle eine diagonale Richtung (entweder "von oben nach unten" oder "von oben nach unten"). Ich möchte eine Reihe berechnen, deren Einträge die Summe der Werte aus dem ursprünglichen DataFrame entlang der gewählten Menge von parallelen Diagonalen sind. Um das Ziel vollständig festzulegen, müssen Sie entscheiden, ob die Diagonalen links verankert oder rechts verankert sind. Für das Folgende nehme ich an, dass sie auf der linken Seite "verankert" sind.

Ich kann das ohne große Probleme machen:

%Vor%

Ich kann die Diagonalsummen "von oben nach unten" wie folgt berechnen:

%Vor%

Und ich kann die Diagonalsummen "von oben nach rechts unten" berechnen, indem ich das shift(-i) nach shift(i) im vorherigen Beispiel umblättere:

%Vor%

Diese Ergebnisse sind alle korrekt (d. h. dieser Code tut, was ich will). Gibt es einen direkteren Weg, um diese Summen in Pandas oder Numpy zu berechnen?

    
8one6 28.01.2016, 16:30
quelle

3 Antworten

6

Sie suchen möglicherweise nach numpy.trace() , dokumentiert hier , um die Spur direkt zu erhalten, oder numpy.diagonal() , um den diagonalen Vektor zu erhalten, hier dokumentiert

Konvertieren Sie zunächst Ihren Datenrahmen mit rectdf.as_matrix()

in eine numplige Matrix

Dann:

%Vor%

Der Offset, der entweder positiv oder negativ sein kann, bewirkt die Verschiebung, die Sie benötigen.

Zum Beispiel, wenn wir tun:

%Vor%

Wir bekommen ausgegeben:

%Vor%

Um dies für eine allgemeine Matrix zu tun, wollen wir den Bereich von -(rows - 1) bis columns , d. h. wenn wir eine Variable rows und eine Variable columns :

haben %Vor%     
Alex Alifimoff 28.01.2016 16:46
quelle
0

Kurze Antwort

Siehe die schnelle, aber komplizierte Funktion am Ende.

Entwicklung

Iteration über die trace ist gut, aber ich bin mir nicht sicher, ob es besser ist als die Pandas-Lösung. Beide beinhalten Iteration - über Diagonalen oder Spalten. Konzeptionell ist es einfacher oder sauberer, aber ich bin mir nicht sicher über die Geschwindigkeit, besonders bei großen Arrays.

Jede Diagonale hat eine andere Länge, [[12],[9,13],...] . Das ist eine große rote Fahne, die uns warnt, dass eine Block-Array-Operation schwierig, wenn nicht unmöglich ist.

Mit scipy.sparse kann ich ein 2d-Array konstruieren, das summiert werden kann, um diese Spuren zu erhalten:

%Vor%

Dieses Sparse-Format speichert sein data in einem 2d-Array mit den notwendigen Verschiebungen. In der Tat produziert Ihr pd.concat etwas ähnliches:

%Vor%

Es sieht so aus, als ob sparse dieses Array data erstellt, indem es mit einem np.zeros beginnt und es mit der entsprechenden Indizierung ausfüllt:

%Vor%

etwas wie:

%Vor%

obwohl ich immer noch eine Möglichkeit brauche, i,j für jede Form zu erstellen. Für j ist es einfach:

%Vor%

Umgestaltung von i

%Vor%

führt mich dazu, es mit:

neu zu erstellen %Vor%

Also zusammen:

%Vor%

Es erfordert mehr Tests für eine Vielzahl von Formen.

Diese Funktion ist schneller als die Iteration über Traces, sogar mit diesem kleinen Array:

%Vor%     
hpaulj 28.01.2016 19:31
quelle
0

Für einen 2D-numpy Array A könnte dies der kürzesten Code Diagonalen zu summieren (?):

%Vor%

Um die gegenüberliegenden Diagonalen zusammenzufassen, können Sie np.fliplr das Array verwenden.

    
user2379410 28.01.2016 23:33
quelle

Tags und Links