python - with - pandas series rename




Umbenennen von Spalten in Pandas (16)

DataFrame - df.rename () wird funktionieren.

df.rename(columns = {'Old Name':'New Name'})

df ist der Datenrahmen, den Sie haben, und der Alte Name ist der Spaltenname, den Sie ändern möchten, dann ist der neue Name der neue Name, an den Sie sich ändern. Diese integrierte DataFrame-Methode macht die Dinge sehr einfach.

Ich habe einen Datenrahmen mit Pandas und Spaltenbeschriftungen, die ich bearbeiten muss, um die ursprünglichen Spaltenbeschriftungen zu ersetzen.

Ich möchte die Spaltennamen in einem DataFrame A ändern, wo die ursprünglichen Spaltennamen sind:

['$a', '$b', '$c', '$d', '$e'] 

zu

['a', 'b', 'c', 'd', 'e'].

Ich habe die bearbeiteten Spaltennamen in einer Liste gespeichert, aber ich weiß nicht, wie ich die Spaltennamen ersetzen soll.


Eine Linie oder Pipeline-Lösungen

Ich konzentriere mich auf zwei Dinge:

  1. OP sagt klar aus

    Ich habe die bearbeiteten Spaltennamen in einer Liste gespeichert, aber ich weiß nicht, wie ich die Spaltennamen ersetzen soll.

    Ich möchte nicht das Problem lösen, wie man '$' oder das erste Zeichen von jeder Spaltenüberschrift entfernt. OP hat diesen Schritt bereits getan. Stattdessen möchte ich mich darauf konzentrieren, das vorhandene columns durch ein neues zu ersetzen, das eine Liste von Ersatzspaltennamen enthält.

  2. df.columns = new wo new ist die Liste der neuen df.columns = new ist so einfach wie es geht. Der Nachteil dieses Ansatzes besteht darin, dass das Spaltenattribut des vorhandenen Datenrahmens bearbeitet werden muss und dies nicht inline erfolgt. Ich werde ein paar Möglichkeiten zeigen, dies per Pipelining durchzuführen, ohne den bestehenden Datenrahmen zu bearbeiten.

Einrichtung 1
Um sich auf die Notwendigkeit der Umbenennung von Ersatzspaltennamen mit einer bereits bestehenden Liste zu konzentrieren, 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 wurde bereits gesagt, dass Sie, wenn Sie ein Wörterbuch hatten, das die alten Spaltennamen neuen Spaltennamen pd.DataFrame.rename , pd.DataFrame.rename 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 problemlos erstellen und es in den Anruf zum rename . Das Folgende nutzt die Tatsache aus, dass wir beim Iterieren über df über jeden Spaltennamen iterieren.

# 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. Aber wenn sie nicht sind, dann bricht das zusammen.

Einrichtung 2
nicht eindeutige Spalten

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 Argument keys

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 am Ende y765 wiederholt. Stattdessen können wir das keys der Funktion pd.concat verwenden, während wir die Spalten von df durchlaufen.

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 einen einzigen dtype für alle Spalten haben. Andernfalls haben Sie am Ende das dtype object für alle Spalten, und die Konvertierung zurück erfordert mehr Wörterbucharbeit.

Einzelner dtype

pd.DataFrame(df.values, df.index, new)

   x098  y765  z432
0     1     3     5
1     2     4     6

Gemischter 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 Trick mit transpose und set_index . pd.DataFrame.set_index können wir einen Index inline setzen, aber es gibt keine entsprechenden set_columns . So können wir transponieren, dann set_index und transponieren zurück. Es gilt jedoch hier die gleiche Einschränkung für einen einzelnen dtype gegenüber einem gemischten dtype von Lösung 3.

Einzelner dtype

df.T.set_index(np.asarray(new)).T

   x098  y765  z432
0     1     3     5
1     2     4     6

Gemischter 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 in pd.DataFrame.rename ein lambda , das jedes Element von new durchläuft
In dieser Lösung übergeben wir ein Lambda, das x nimmt, aber dann ignoriert. Es dauert auch ein y aber erwartet es nicht. Stattdessen wird ein Iterator als Standardwert angegeben, und ich kann ihn dann verwenden, um nacheinander durchzugehen, ohne Rücksicht darauf, was der Wert von x ist.

df.rename(columns=lambda x, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6

Und wie mir von den Leuten im sopython- Chat gesagt wurde , wenn ich ein * zwischen x und y hinzufüge, kann ich meine y Variable schützen. In diesem Zusammenhang glaube ich nicht, dass es geschützt werden muss. Es ist immer noch erwähnenswert.

df.rename(columns=lambda x, *, y=iter(new): next(y))

   x098  y765  z432
0     1     3     5
1     2     4     6

Spaltennamen vs Namen der Serie

Ich möchte ein bisschen erklären, was hinter den Kulissen passiert.

Dataframes sind eine Reihe von Serien.

Serien wiederum sind eine Erweiterung eines numpy.array

numpy.array s hat eine Eigenschaft .name

Dies ist der Name der Serie. Es ist selten, dass Pandas diese Eigenschaft respektieren, aber sie verweilt an einigen Stellen und kann verwendet werden, um einige Pandas zu hacken.

Benennung der Spaltenliste

Viele Antworten df.columns , dass das df.columns Attribut eine list df.columns es sich tatsächlich um eine Series . Dies bedeutet, dass es ein Attribut .name hat.

Dies geschieht, wenn Sie den Namen der Spalten Series möchten.

df.columns = ['column_one', 'column_two']
df.columns.names = ['name of the list of columns']
df.index.names = ['name of the index']

name of the list of columns     column_one  column_two
name of the index       
0                                    4           1
1                                    5           2
2                                    6           3

Beachten Sie, dass der Name des Index immer eine Spalte niedriger ist.

Artefakte, die verweilen

Das Attribut .name verweilt manchmal. Wenn Sie df.columns = ['one', 'two'] df.one.name wird df.one.name 'one' .

Wenn Sie df.one.name = 'three' dann geben df.columns Ihnen immer noch ['one', 'two'] , und df.one.name gibt Ihnen 'three'

ABER

pd.DataFrame(df.one) wird zurückgeben

    three
0       1
1       2
2       3

Weil Pandas den Namen der bereits definierten Series wiederverwenden.

Mehrstufige Spaltennamen

Pandas hat Möglichkeiten, mehrschichtige Spaltennamen zu erstellen. Es ist nicht so viel Magie involviert, aber ich wollte das auch in meiner Antwort behandeln, da ich niemanden sehe, der das hier aufgreift.

    |one            |
    |one      |two  |
0   |  4      |  1  |
1   |  5      |  2  |
2   |  6      |  3  |

Dies kann leicht erreicht werden, indem Spalten wie folgt auf Listen gesetzt werden:

df.columns = [['one', 'one'], ['one', 'two']]

Beachten Sie, dass diese Vorgehensweise für einen MultiIndex nicht funktioniert. Für einen MultiIndex müssen Sie Folgendes tun:

>>> df = pd.DataFrame({('$a','$x'):[1,2], ('$b','$y'): [3,4], ('e','f'):[5,6]})
>>> df
   $a $b  e
   $x $y  f
0  1  3  5
1  2  4  6
>>> rename = {('$a','$x'):('a','x'), ('$b','$y'):('b','y')}
>>> df.columns = pandas.MultiIndex.from_tuples([
        rename.get(item, item) for item in df.columns.tolist()])
>>> df
   a  b  e
   x  y  f
0  1  3  5
1  2  4  6

Die df.rename() kann eine Funktion annehmen, zum Beispiel:

In [11]: df.columns
Out[11]: Index([u'$a', u'$b', u'$c', u'$d', u'$e'], dtype=object)

In [12]: df.rename(columns=lambda x: x[1:], inplace=True)

In [13]: df.columns
Out[13]: Index([u'a', u'b', u'c', u'd', u'e'], dtype=object)

Eine andere Möglichkeit, die ursprünglichen Spaltenbeschriftungen zu ersetzen, besteht darin, die unerwünschten Zeichen (hier $) von den ursprünglichen Spaltenbeschriftungen zu entfernen.

Dies könnte getan worden sein, indem eine for-Schleife über df.columns ausgeführt wird und die entfernten Spalten an df.columns angehängt werden.

Stattdessen können wir dies in einer einzigen Anweisung sauber machen, indem wir Listenverständnis wie unten verwenden:

df.columns = [col.strip('$') for col in df.columns]

( strip Methode in Python entfernt das angegebene Zeichen vom Anfang und vom Ende der Zeichenfolge.)


Ich denke diese Methode ist nützlich:

df.rename(columns={"old_column_name1":"new_column_name1", "old_column_name2":"new_column_name2"})

Mit dieser Methode können Sie die Spaltennamen einzeln ändern.


Ich weiß, dass diese Frage und Antwort zu Tode gekaut wurde. Aber ich erwähnte es als Inspiration für eines der Probleme, die ich hatte. Ich konnte es lösen mit Bits und Stücke aus verschiedenen Antworten und somit meine Antwort für den Fall, dass jemand es benötigt.

Meine Methode ist generisch, wobei Sie zusätzliche Trennzeichen durch Kommata hinzufügen können, die delimiters= Variable und zukunftssicher trennen.

Arbeitscode:

import pandas as pd
import re


df = pd.DataFrame({'$a':[1,2], '$b': [3,4],'$c':[5,6], '$d': [7,8], '$e': [9,10]})

delimiters = '$'
matchPattern = '|'.join(map(re.escape, delimiters))
df.columns = [re.split(matchPattern, i)[1] for i in df.columns ]

Ausgabe:

>>> df
   $a  $b  $c  $d  $e
0   1   3   5   7   9
1   2   4   6   8  10

>>> df
   a  b  c  d   e
0  1  3  5  7   9
1  2  4  6  8  10

Versuche dies. Für mich geht das

df.rename(index=str, columns={"$a": "a", "$b": "b", "$c" : "c", "$d" : "d", "$e" : "e"})

Verwenden Sie die Funktion df.rename() und verweisen Sie auf die Spalten, die umbenannt werden sollen. Nicht alle Spalten müssen umbenannt werden:

df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})
# Or rename the existing DataFrame (rather than creating a copy) 
df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'}, inplace=True)

Wenn Sie mit vielen Spalten arbeiten müssen, die von dem Bereitstellungssystem außerhalb Ihrer Kontrolle benannt wurden, habe ich den folgenden Ansatz entwickelt, bei dem es sich um eine Kombination aus einem allgemeinen Ansatz und spezifischen Ersetzungen auf einmal handelt.

Ich erstelle zuerst ein Wörterbuch aus den Namen der Datenrahmenspalten unter Verwendung von Regexausdrücken, um bestimmte Anhänge von Spaltennamen wegzuwerfen, und dann füge ich spezifische Ersetzungen dem Wörterbuch hinzu, um Kernspalten zu benennen, wie später in der empfangenden Datenbank erwartet.

Dies wird dann auf den Datenrahmen auf einmal angewendet.

dict=dict(zip(df.columns,df.columns.str.replace('(:S$|:C1$|:L$|:D$|\.Serial:L$)','')))
dict['brand_timeseries:C1']='BTS'
dict['respid:L']='RespID'
dict['country:C1']='CountryID
dict['pim1:D']='pim_actual'
df.rename(columns=dict, inplace=True)


.columns Sie es .columns dem .columns Attribut zu:

>>> df = pd.DataFrame({'$a':[1,2], '$b': [10,20]})
>>> df.columns = ['a', 'b']
>>> df
   a   b
0  1  10
1  2  20

df.columns = ['a', 'b',index=False] Sie die df.columns = ['a', 'b',index=False] nicht df.columns = ['a', 'b',index=False]


df = pd.DataFrame({'$a': [1], '$b': [1], '$c': [1], '$d': [1], '$e': [1]})

Wenn Ihre neue Liste von Spalten in der gleichen Reihenfolge wie die vorhandenen Spalten ist, ist die Zuweisung einfach:

new_cols = ['a', 'b', 'c', 'd', 'e']
df.columns = new_cols
>>> df
   a  b  c  d  e
0  1  1  1  1  1

Wenn Sie ein Wörterbuch mit alten Spaltennamen mit neuen Spaltennamen versehen haben, können Sie Folgendes tun:

d = {'$a': 'a', '$b': 'b', '$c': 'c', '$d': 'd', '$e': 'e'}
df.columns = df.columns.map(lambda col: d[col])  # Or `.map(d.get)` as pointed out by @PiRSquared.
>>> df
   a  b  c  d  e
0  1  1  1  1  1

Wenn Sie keine Liste oder Wörterbuchzuordnung haben, können Sie das führende $ -Symbol über ein Listenverständnis entfernen:

df.columns = [col[1:] if col[0] == '$' else col for col in df]

df.columns = ['a', 'b', 'c', 'd', 'e']

Es ersetzt die vorhandenen Namen durch die von Ihnen angegebenen Namen in der von Ihnen angegebenen Reihenfolge.

Sie können sie auch nach Index wie folgt zuweisen:

df.columns.values[2] = 'c'    #renames the 2nd column to 'c' (in position #3)




rename