Benennen Sie bestimmte Spalten in Pandas um


182

Ich habe einen Datenrahmen namens data. Wie würde ich den einzigen Spaltenkopf umbenennen? Zum Beispiel gdpzu log(gdp)?

data =
    y  gdp  cap
0   1    2    5
1   2    3    9
2   8    7    2
3   3    4    7
4   6    7    7
5   4    8    3
6   8    2    8
7   9    9   10
8   6    6    4
9  10   10    7

7
Es gibt definitiv Überschneidungen, aber aus "Umbenennen von Spalten in Pandas" war mir nicht sofort klar, dass Sie ein einzelnes Spaltenelement zum Umbenennen auswählen können. Im Nachhinein ist es natürlich offensichtlich, und wenn ich tiefer gegraben hätte, hätte ich das wahrscheinlich herausgefunden, aber ich denke, diese Frage / Antwort ist besser, um darauf hinzuweisen.
Jeremiahbuddha

Antworten:


359
data.rename(columns={'gdp':'log(gdp)'}, inplace=True)

Die renameShow, dass es ein Diktat als Parameter akzeptiert, columnsso dass Sie nur ein Diktat mit einem einzigen Eintrag übergeben.

Siehe auch verwandte


3
Dies dauert bei einem großen Datenrahmen sehr lange. Ich glaube also, dass dies eine Art Kopieren des gesamten Datenrahmens in den Speicher bewirkt.
Elgehelge

1
@elgehelge sollte es nicht tun, die meisten Pandas-Operationen geben eine Kopie zurück und einige akzeptieren einen inplaceParameter. Wenn dieser Parameter ignoriert wird, ist dies ein Fehler. Können Sie Timings mit und ohne Parameter durchführen, versuchen Sie auch so etwas new_df = df.rename(columns={'new_name':'old_name'})und sehen Sie, ob dies der Fall ist ist schneller oder nicht
EdChum

1
@ EdChum Danke. Durch Entfernen des inplaceParameters wurde die Zeit von 14 Sekunden auf 26 Sekunden fast verdoppelt. Aber 14 Sekunden noch eine ziemlich lange Zeit, nur um den Header zu ändern ..
Elgehelge

2
Nur eine Anmerkung, Vorsicht! Wenn die Zielspalte nicht vorhanden ist (falsche Schreibweise des Namens oder so), führt dies zu nichts ohne Fehler oder Warnung.
Amir

1
@Quastiat Es ist ein bisschen deprimierend, warum einige dieser einfachen Operationen nur schneller sind, wenn man eine Liste versteht. Grundsätzlich sollte es jedoch keine Rolle spielen, es sei denn, Sie haben viele Spalten auf einem großen df umbenannt
EdChum

27

Eine viel schnellere Implementierung wäre die Verwendung, list-comprehensionwenn Sie eine einzelne Spalte umbenennen müssen.

df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]

Wenn mehrere Spalten umbenannt werden müssen, verwenden Sie entweder bedingte Ausdrücke wie:

df.columns = ['log(gdp)' if x=='gdp' else 'cap_mod' if x=='cap' else x for x in df.columns]

Oder erstellen Sie eine Zuordnung mit a dictionaryund führen list-comprehensionSie die getOperation mit der Operation aus, indem Sie den Standardwert als alten Namen festlegen:

col_dict = {'gdp': 'log(gdp)', 'cap': 'cap_mod'}   ## key→old name, value→new name

df.columns = [col_dict.get(x, x) for x in df.columns]

Timings:

%%timeit
df.rename(columns={'gdp':'log(gdp)'}, inplace=True)
10000 loops, best of 3: 168 µs per loop

%%timeit
df.columns = ['log(gdp)' if x=='gdp' else x for x in df.columns]
10000 loops, best of 3: 58.5 µs per loop

Ich würde diese Methode gerne verwenden, aber leider funktioniert sie nicht, pd.merge_asof()weil es sich um einen Ausdruck handelt :(.
thdoan

14

Wie benenne ich eine bestimmte Spalte in Pandas um?

Ab Version 0.24 + können Sie jeweils eine (oder mehrere) Spalten umbenennen.

Wenn Sie ALLE Spalten gleichzeitig umbenennen müssen,

  • DataFrame.set_axis()Methode mit axis=1. Übergeben Sie eine listenartige Sequenz. Optionen für die direkte Änderung sind ebenfalls verfügbar.

rename mit axis=1

df = pd.DataFrame('x', columns=['y', 'gdp', 'cap'], index=range(5))
df

   y gdp cap
0  x   x   x
1  x   x   x
2  x   x   x
3  x   x   x
4  x   x   x

Ab 0,21 können Sie jetzt einen axisParameter angeben mit rename:

df.rename({'gdp':'log(gdp)'}, axis=1)
# df.rename({'gdp':'log(gdp)'}, axis='columns')
    
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

(Beachten Sie, dass dies renamenicht standardmäßig vorhanden ist, sodass Sie das Ergebnis zurückweisen müssen .)

Dieser Zusatz wurde vorgenommen, um die Konsistenz mit dem Rest der API zu verbessern. Das neue axisArgument ist analog zum columnsParameter - sie machen dasselbe.

df.rename(columns={'gdp': 'log(gdp)'})

   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

rename Akzeptiert auch einen Rückruf, der für jede Spalte einmal aufgerufen wird.

df.rename(lambda x: x[0], axis=1)
# df.rename(lambda x: x[0], axis='columns')

   y  g  c
0  x  x  x
1  x  x  x
2  x  x  x
3  x  x  x
4  x  x  x

Für dieses spezielle Szenario möchten Sie verwenden

df.rename(lambda x: 'log(gdp)' if x == 'gdp' else x, axis=1)

Index.str.replace

Ähnlich wie bei der replaceMethode der Zeichenfolgen in Python definieren pandas Index und Series (nur Objekttyp) eine ("vektorisierte") str.replaceMethode für das Ersetzen von Zeichenfolgen und Regex.

df.columns = df.columns.str.replace('gdp', 'log(gdp)')
df
 
   y log(gdp) cap
0  x        x   x
1  x        x   x
2  x        x   x
3  x        x   x
4  x        x   x

Dies hat gegenüber den anderen Methoden den Vorteil, dass str.replaceRegex unterstützt wird (standardmäßig aktiviert). Weitere Informationen finden Sie in den Dokumenten.


Übergeben einer Liste an set_axismitaxis=1

Rufen Sie set_axismit einer Liste von Headern an. Die Liste muss der Spalten- / Indexgröße entsprechen. set_axismutiert standardmäßig den ursprünglichen DataFrame, Sie können jedoch angeben inplace=False, dass eine geänderte Kopie zurückgegeben werden soll.

df.set_axis(['cap', 'log(gdp)', 'y'], axis=1, inplace=False)
# df.set_axis(['cap', 'log(gdp)', 'y'], axis='columns', inplace=False)

  cap log(gdp)  y
0   x        x  x
1   x        x  x
2   x        x  x
3   x        x  x
4   x        x  x

Hinweis: In zukünftigen Versionen inplacewird standardmäßig verwendet True.

Methodenverkettung
Warum wählen, set_axiswenn wir bereits eine effiziente Möglichkeit haben, Spalten zuzuweisen df.columns = ...? Wie von Ted Petrou in [dieser Antwort] gezeigt ( https://stackoverflow.com/a/46912050/4909087 )set_axis hilfreich, wenn Sie versuchen, Methoden zu verketten.

Vergleichen Sie

# new for pandas 0.21+
df.some_method1()
  .some_method2()
  .set_axis()
  .some_method3()

Gegen

# old way
df1 = df.some_method1()
        .some_method2()
df1.columns = columns
df1.some_method3()

Ersteres ist eine natürlichere und frei fließende Syntax.


3

Es gibt mindestens fünf verschiedene Möglichkeiten, bestimmte Spalten in Pandas umzubenennen, und ich habe sie unten zusammen mit Links zu den ursprünglichen Antworten aufgelistet. Ich habe diese Methoden auch zeitlich festgelegt und festgestellt, dass sie ungefähr gleich funktionieren (obwohl YMMV von Ihrem Datensatz und Szenario abhängt). Der Testfall ist unten Spalten zu umbenennen , A M N Zum A2 M2 N2 Z2in einem Datenrahmen mit Spalten Aauf Zeine Million Zeilen enthalten.

# Import required modules
import numpy as np
import pandas as pd
import timeit

# Create sample data
df = pd.DataFrame(np.random.randint(0,9999,size=(1000000, 26)), columns=list('ABCDEFGHIJKLMNOPQRSTUVWXYZ'))

# Standard way - https://stackoverflow.com/a/19758398/452587
def method_1():
    df_renamed = df.rename(columns={'A': 'A2', 'M': 'M2', 'N': 'N2', 'Z': 'Z2'})

# Lambda function - https://stackoverflow.com/a/16770353/452587
def method_2():
    df_renamed = df.rename(columns=lambda x: x + '2' if x in ['A', 'M', 'N', 'Z'] else x)

# Mapping function - https://stackoverflow.com/a/19758398/452587
def rename_some(x):
    if x=='A' or x=='M' or x=='N' or x=='Z':
        return x + '2'
    return x
def method_3():
    df_renamed = df.rename(columns=rename_some)

# Dictionary comprehension - https://stackoverflow.com/a/58143182/452587
def method_4():
    df_renamed = df.rename(columns={col: col + '2' for col in df.columns[
        np.asarray([i for i, col in enumerate(df.columns) if 'A' in col or 'M' in col or 'N' in col or 'Z' in col])
    ]})

# Dictionary comprehension - https://stackoverflow.com/a/38101084/452587
def method_5():
    df_renamed = df.rename(columns=dict(zip(df[['A', 'M', 'N', 'Z']], ['A2', 'M2', 'N2', 'Z2'])))

print('Method 1:', timeit.timeit(method_1, number=10))
print('Method 2:', timeit.timeit(method_2, number=10))
print('Method 3:', timeit.timeit(method_3, number=10))
print('Method 4:', timeit.timeit(method_4, number=10))
print('Method 5:', timeit.timeit(method_5, number=10))

Ausgabe:

Method 1: 3.650640267
Method 2: 3.163998427
Method 3: 2.998530871
Method 4: 2.9918436889999995
Method 5: 3.2436501520000007

Verwenden Sie die Methode, die für Sie am intuitivsten und für Sie am einfachsten in Ihrer Anwendung zu implementieren ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.