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 columns
Objekt durch ein neues zu ersetzen, wenn eine Liste mit Ersatzspaltennamen vorhanden ist.
df.columns = new
Wo new
ist die Liste der neuen Spaltennamen ist so einfach wie es nur geht. Der Nachteil dieses Ansatzes besteht darin, dass das columns
Attribut 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 df
mit 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 df
jeder 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 keys
Argument
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 new
Liste nicht als Spaltennamen zugeordnet. Wir haben uns wiederholt y765
. Stattdessen können wir das keys
Argument der pd.concat
Funktion 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 dtype
für alle Spalten eine einzige haben . Andernfalls erhalten Sie dtype
object
alle 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 transpose
und set_index
. pd.DataFrame.set_index
ermöglicht es uns, einen Index inline zu setzen, aber es gibt keine entsprechenden set_columns
. Wir können also transponieren set_index
und zurück transponieren. Allerdings ist die gleiche Single im dtype
Vergleich zu gemischtem dtype
gilt 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 lambda
In 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 x
und hinzufüge . In diesem Zusammenhang glaube ich jedoch nicht, dass es geschützt werden muss. Es ist immer noch erwähnenswert.y
y
df.rename(columns=lambda x, *, y=iter(new): next(y))
x098 y765 z432
0 1 3 5
1 2 4 6