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:
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?
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()
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
:
Siehe die schnelle, aber komplizierte Funktion am Ende.
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:
Dieses Sparse-Format speichert sein data
in einem 2d-Array mit den notwendigen Verschiebungen. In der Tat produziert Ihr pd.concat
etwas ähnliches:
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:
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:
Umgestaltung von i
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% Für einen 2D-numpy Array A
könnte dies der kürzesten Code Diagonalen zu summieren (?):
Um die gegenüberliegenden Diagonalen zusammenzufassen, können Sie np.fliplr
das Array verwenden.