Rinomina le colonne specifiche nei panda


182

Ho un dataframe chiamato data. Come rinominerei l'unica intestazione di colonna? Per esempio gdpa 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
C'è sicuramente una sovrapposizione, ma da "Rinominare le colonne nei panda" non mi è stato subito chiaro che si potesse individuare un elemento di colonna solitario per rinominarlo. Certo, a posteriori è ovvio, e se avessi scavato più a fondo probabilmente lo avrei capito, ma penso che questa domanda / risposta sia migliore nel sottolinearlo.
jeremiahbuddha,

Risposte:


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

Lo renamespettacolo che accetta un dict come parametro per columnscui basta passare un dict con una sola voce.

Vedi anche correlati


3
Questo richiede molto tempo su un grande frame di dati, quindi credo che questo faccia una sorta di copia dell'intero frame di dati in memoria?
elgehelge,

1
@elgehelge non dovrebbe fare, la maggior parte delle operazioni panda restituirà una copia e alcuni accettano un inplaceparametro, se ignora questo parametro allora questo è un bug, puoi fare i tempi con e senza il parametro, prova anche qualcosa di simile new_df = df.rename(columns={'new_name':'old_name'})e vedi se questo è più veloce o no
EdChum

1
@ EdChum Grazie. La rimozione del inplaceparametro ha quasi raddoppiato il tempo da 14 secondi a 26 secondi. Ma 14 secondi sono ancora parecchio tempo solo per cambiare intestazione ...
elgehelge,

2
solo una nota, attenzione! se la colonna target non esiste, (scrivendo erroneamente il nome o giù di lì) questo non farà nulla senza errori o avvertenze.
Amir,

1
@Quastiat è un po 'deprimente perché alcune di queste semplici operazioni siano più veloci facendo una comprensione della lista. Fondamentalmente, a meno che tu non abbia un df molto grande, allora non dovrebbe importare davvero a meno che tu non stia rinominando molte colonne su un grande df
EdChum,

27

Un'implementazione molto più veloce sarebbe da utilizzare list-comprehensionse è necessario rinominare una singola colonna.

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

Se è necessario rinominare più colonne, utilizzare espressioni condizionali come:

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

Oppure, costruisci una mappatura usando a dictionaryed esegui l'operazione list-comprehensionwith getis impostando il valore predefinito come vecchio nome:

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]

Tempi:

%%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

Mi piacerebbe utilizzare questo metodo, ma purtroppo non funziona in pd.merge_asof()quanto si tratta di un'espressione :(.
thdoan

14

Come posso rinominare una colonna specifica in Panda?

Da v0.24 +, per rinominare una (o più) colonne alla volta,

Se devi rinominare TUTTE le colonne contemporaneamente,

  • DataFrame.set_axis()metodo con axis=1. Passa una sequenza simile a un elenco. Sono disponibili anche opzioni per modifiche sul posto.

rename con 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

Con 0.21+, ora puoi specificare un axisparametro con 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

(Si noti che renamenon è sul posto per impostazione predefinita, quindi sarà necessario assegnare nuovamente il risultato .)

Questa aggiunta è stata apportata per migliorare la coerenza con il resto dell'API. Il nuovo axisargomento è analogo al columnsparametro: fanno la stessa cosa.

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 accetta anche un callback che viene chiamato una volta per ogni colonna.

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

Per questo scenario specifico, si desidera utilizzare

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

Index.str.replace

Simile al replacemetodo delle stringhe in python, Index panda e Series (solo tipo dtype) definiscono un str.replacemetodo ("vettoriale") per la sostituzione basata su stringhe e 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

Il vantaggio di questo rispetto agli altri metodi è che str.replacesupporta regex (abilitato per impostazione predefinita). Consulta i documenti per ulteriori informazioni.


Passando un elenco a set_axisconaxis=1

Chiama set_axiscon un elenco di intestazioni. L'elenco deve essere uguale in lunghezza alla dimensione di colonne / indice. set_axismuta il DataFrame originale per impostazione predefinita, ma puoi specificare inplace=Falsedi restituire una copia modificata.

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

Nota: nelle versioni future, l' inplaceimpostazione predefinita è True.

Metodo di concatenamento
Perché scegliere set_axisquando abbiamo già un modo efficiente di assegnare colonne df.columns = ...? Come mostrato da Ted Petrou in [questa risposta], ( https://stackoverflow.com/a/46912050/4909087 ) set_axisè utile quando si tenta di concatenare i metodi.

Confrontare

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

Contro

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

Il primo è una sintassi più naturale e a flusso libero.


3

Esistono almeno cinque modi diversi per rinominare colonne specifiche nei panda e le ho elencate di seguito insieme ai collegamenti alle risposte originali. Ho anche cronometrato questi metodi e ho scoperto che funzionano allo stesso modo (anche se YMMV dipende dal set di dati e dallo scenario). Il banco di prova di seguito è rinominare colonne A M N Za A2 M2 N2 Z2in un dataframe con colonne Aa Zcontenente un milione di righe.

# 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))

Produzione:

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

Utilizza il metodo più intuitivo per te e più semplice da implementare nella tua applicazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.