Einzeilige oder Pipeline-Lösungen
Ich werde mich auf zwei Dinge konzentrieren:
OP stellt klar fest
Ich habe die bearbeiteten Spaltennamen in einer Liste gespeichert, weiß aber nicht, wie ich die Spaltennamen ersetzen soll.
Ich möchte nicht das Problem lösen, wie '$'das erste Zeichen aus jeder Spaltenüberschrift ersetzt oder entfernt werden kann. OP hat diesen Schritt bereits ausgeführt. Stattdessen möchte ich mich darauf konzentrieren, das vorhandene columnsObjekt durch ein neues zu ersetzen, wenn eine Liste mit Ersatzspaltennamen vorhanden ist.
df.columns = newWo newist die Liste der neuen Spaltennamen ist so einfach wie es nur geht. Der Nachteil dieses Ansatzes besteht darin, dass das columnsAttribut des vorhandenen Datenrahmens bearbeitet werden muss und nicht inline ausgeführt wird. Ich werde einige Möglichkeiten zeigen, wie dies per Pipelining durchgeführt werden kann, ohne den vorhandenen Datenrahmen zu bearbeiten.
Setup 1
Um sich auf die Notwendigkeit zu konzentrieren, Spaltennamen durch eine bereits vorhandene Liste zu ersetzen, erstelle ich einen neuen Beispieldatenrahmen dfmit anfänglichen Spaltennamen und nicht verwandten neuen Spaltennamen.
df = pd.DataFrame({'Jack': [1, 2], 'Mahesh': [3, 4], 'Xin': [5, 6]})
new = ['x098', 'y765', 'z432']
df
Jack Mahesh Xin
0 1 3 5
1 2 4 6
Lösung 1
pd.DataFrame.rename
Es ist gesagt worden , dass bereits , wenn Sie ein Wörterbuch - Mapping der alten Spaltennamen an den neuen Spaltennamen haben, konnte man verwenden pd.DataFrame.rename.
d = {'Jack': 'x098', 'Mahesh': 'y765', 'Xin': 'z432'}
df.rename(columns=d)
x098 y765 z432
0 1 3 5
1 2 4 6
Sie können dieses Wörterbuch jedoch einfach erstellen und in den Aufruf von aufnehmen rename. Im Folgenden wird die Tatsache ausgenutzt, dass beim Iterieren dfjeder Spaltenname durchlaufen wird.
# given just a list of new column names
df.rename(columns=dict(zip(df, new)))
x098 y765 z432
0 1 3 5
1 2 4 6
Dies funktioniert hervorragend, wenn Ihre ursprünglichen Spaltennamen eindeutig sind. Wenn dies nicht der Fall ist, bricht dies zusammen.
Richten Sie 2
nicht eindeutige Spalten ein
df = pd.DataFrame(
[[1, 3, 5], [2, 4, 6]],
columns=['Mahesh', 'Mahesh', 'Xin']
)
new = ['x098', 'y765', 'z432']
df
Mahesh Mahesh Xin
0 1 3 5
1 2 4 6
Lösung 2
pd.concat mit dem keysArgument
Beachten Sie zunächst, was passiert, wenn wir versuchen, Lösung 1 zu verwenden:
df.rename(columns=dict(zip(df, new)))
y765 y765 z432
0 1 3 5
1 2 4 6
Wir haben die newListe nicht als Spaltennamen zugeordnet. Wir haben uns wiederholt y765. Stattdessen können wir das keysArgument der pd.concatFunktion verwenden, während wir durch die Spalten von iterieren df.
pd.concat([c for _, c in df.items()], axis=1, keys=new)
x098 y765 z432
0 1 3 5
1 2 4 6
Lösung 3
Rekonstruieren. Dies sollte nur verwendet werden, wenn Sie dtypefür alle Spalten eine einzige haben . Andernfalls erhalten Sie dtype objectalle Spalten, und das Zurückkonvertieren erfordert mehr Wörterbucharbeit.
Single dtype
pd.DataFrame(df.values, df.index, new)
x098 y765 z432
0 1 3 5
1 2 4 6
Gemischt dtype
pd.DataFrame(df.values, df.index, new).astype(dict(zip(new, df.dtypes)))
x098 y765 z432
0 1 3 5
1 2 4 6
Lösung 4
Dies ist ein kniffliger Trick mit transposeund set_index. pd.DataFrame.set_indexermöglicht es uns, einen Index inline zu setzen, aber es gibt keine entsprechenden set_columns. Wir können also transponieren set_indexund zurück transponieren. Allerdings ist die gleiche Single im dtypeVergleich zu gemischtem dtypegilt Vorbehalt aus der Lösung 3 hier.
Single dtype
df.T.set_index(np.asarray(new)).T
x098 y765 z432
0 1 3 5
1 2 4 6
Gemischt dtype
df.T.set_index(np.asarray(new)).T.astype(dict(zip(new, df.dtypes)))
x098 y765 z432
0 1 3 5
1 2 4 6
Lösung 5
Verwenden Sie ein lambdaIn pd.DataFrame.rename, das jedes Element von durchläuft. new
In dieser Lösung übergeben wir ein Lambda, das es nimmt x, es dann aber ignoriert. Es dauert auch ein y, aber erwartet es nicht. Stattdessen wird ein Iterator als Standardwert angegeben, und ich kann diesen dann verwenden, um einen nach dem anderen zu durchlaufen, ohne Rücksicht auf den Wert von x.
df.rename(columns=lambda x, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6
Und wie mir die Leute im Sopython- Chat gesagt haben , kann ich meine Variable schützen , wenn ich *dazwischen ein xund hinzufüge . In diesem Zusammenhang glaube ich jedoch nicht, dass es geschützt werden muss. Es ist immer noch erwähnenswert.yy
df.rename(columns=lambda x, *, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6