Festlegen der Werte auf der diagonalen der pandas.DataFrame
Habe ich ein pandas dataframe ich möchte se der diagonalen zu 0
import numpy
import pandas
df = pandas.DataFrame(numpy.random.rand(5,5))
df
Out[6]:
0 1 2 3 4
0 0.536596 0.674319 0.032815 0.908086 0.215334
1 0.735022 0.954506 0.889162 0.711610 0.415118
2 0.119985 0.979056 0.901891 0.687829 0.947549
3 0.186921 0.899178 0.296294 0.521104 0.638924
4 0.354053 0.060022 0.275224 0.635054 0.075738
5 rows × 5 columns
nun möchte ich um die Diagonale zu 0:
for i in range(len(df.index)):
for j in range(len(df.columns)):
if i==j:
df.loc[i,j] = 0
df
Out[9]:
0 1 2 3 4
0 0.000000 0.674319 0.032815 0.908086 0.215334
1 0.735022 0.000000 0.889162 0.711610 0.415118
2 0.119985 0.979056 0.000000 0.687829 0.947549
3 0.186921 0.899178 0.296294 0.000000 0.638924
4 0.354053 0.060022 0.275224 0.635054 0.000000
5 rows × 5 columns
aber es muss doch eine mehr pythonic way als das!?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Beachten Sie, dass dies nur funktioniert, wenn
df
hat die gleiche Anzahl von Zeilen wie Spalten. Einen anderen Weg, der funktioniert für beliebige Formen ist die Verwendung np.fill_diagonal:np.fill_diagonal
ist, dass es in jeder DataFrame oder die matrix können Sie in den Arbeitsspeicher passen, ohne mehr Speicher. Die "fill" arbeiten geschehen effizient "im Ort" in Erinnerung und lassen dieindex
undcolumns
und andere Attribute des DataFrame intakt.Beide Ansätze in unutbu Antwort davon ausgehen, dass die Bezeichnungen irrelevant sind (Sie arbeiten nach dem zugrunde liegenden Werte).
Den OP-code funktioniert mit
.loc
und so ist der label-Basis statt (d.h. setzen Sie eine 0 an Zellen in der Zeile-Spalte mit gleichen Beschriftungen, anstatt in den Zellen befindet sich auf der diagonal - zugegeben, das ist irrelevant in dem spezifischen Beispiel gegeben, in denen Etiketten sind nur Positionen).Benötigen Sie das "label-based" Diagonale Füllung (arbeiten mit einem
DataFrame
beschreiben eine unvollständige Nachbarschaft-matrix), ist der einfachste Ansatz, ich könnte kommen mit war:Diese Lösung ist vektorisiert und sehr schnell, und wenn die andere vorgeschlagene Lösung funktioniert für jede Spalte die Namen und die Größe der matrix df.
Leistung auf Dataframe 507 Spalten und Zeilen
1000 loops, best of 3: 145 µs pro Schleife
Hier ist ein hack für mich gearbeitet:
numpy.fill_diagonal
? Auch, hinzufügen von Feldern zu bestehenden Bibliothek-Datentypen ist nicht eine gute Sache zu beraten.Mit
np.fill_diagonal(df.values, 1)
Ist die einfachste, aber Sie müssen sicherstellen, dass Ihre Spalten, die alle denselben Datentyp haben, ich hatte eine Mischung aus np.float64 und python schwimmt und es würde nur den Effekt der numpy-Werte. zu beheben, müssen Sie zu werfen, alles zu numpy.