Rinominare le colonne nei panda


1827

Ho un DataFrame che usa i panda e le etichette delle colonne che devo modificare per sostituire le etichette delle colonne originali.

Vorrei cambiare i nomi delle colonne in un DataFrame in Acui i nomi delle colonne originali sono:

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

per

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

Ho i nomi delle colonne modificati memorizzati in un elenco, ma non so come sostituire i nomi delle colonne.


1
Potresti andare a dare un'occhiata ai documenti ufficiali che coprono la ridenominazione delle etichette delle colonne: pandas.pydata.org/pandas-docs/stable/user_guide/text.html
ccpizza

Risposte:


1829

Basta assegnarlo .columnsall'attributo:

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

303
È possibile cambiare il nome di una singola colonna?
Ericmjl,

112
@ericmjl: supponi di voler cambiare il nome della prima variabile di df. Quindi puoi fare qualcosa del tipo:new_columns = df.columns.values; new_columns[0] = 'XX'; df.columns = new_columns
cd98

54
Sembra che avresti potuto semplicemente fare df.columns.values ​​[0] = 'XX'
RAY

25
Sto scherzando, @RAY - non farlo. Sembra che sia un elenco generato indipendentemente da qualunque indicizzazione memorizzi il nome della colonna. Fa un buon lavoro distruggendo i nomi delle colonne per il tuo df ...
Mitch Flax

433
@ericmjl sìdf.rename(columns = {'$b':'B'}, inplace = True)
nachocab,

2848

COLONNE SPECIFICHE DI RINAME

Utilizzare la df.rename()funzione e fare riferimento alle colonne da rinominare. Non tutte le colonne devono essere rinominate:

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)

Esempio di codice minimo

df = pd.DataFrame('x', index=range(3), columns=list('abcde'))
df

   a  b  c  d  e
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

I seguenti metodi funzionano tutti e producono lo stesso output:

df2 = df.rename({'a': 'X', 'b': 'Y'}, axis=1)  # new method
df2 = df.rename({'a': 'X', 'b': 'Y'}, axis='columns')
df2 = df.rename(columns={'a': 'X', 'b': 'Y'})  # old method  

df2

   X  Y  c  d  e
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

Ricorda di assegnare nuovamente il risultato, poiché la modifica non è in atto. In alternativa, specificare inplace=True:

df.rename({'a': 'X', 'b': 'Y'}, axis=1, inplace=True)
df

   X  Y  c  d  e
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

Da v0.25, è inoltre possibile specificare errors='raise'di generare errori se viene specificato un nome-colonna da rinominare non valido. Vedi documenti v0.25rename() .


Riorganizzare le intestazioni della colonna

Utilizzare df.set_axis()con axis=1e inplace=False(per restituire una copia).

df2 = df.set_axis(['V', 'W', 'X', 'Y', 'Z'], axis=1, inplace=False)
df2

   V  W  X  Y  Z
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

Ciò restituisce una copia, ma è possibile modificare il DataFrame sul posto impostando inplace=True(questo è il comportamento predefinito per le versioni <= 0.24 ma è probabile che cambi in futuro).

Puoi anche assegnare direttamente le intestazioni:

df.columns = ['V', 'W', 'X', 'Y', 'Z']
df

   V  W  X  Y  Z
0  x  x  x  x  x
1  x  x  x  x  x
2  x  x  x  x  x

2
quando lo faccio con un frame di dati a 6 colonne (dataframe <premi invio>) la rappresentazione abbreviata: code<class 'pandas.core.frame.DataFrame'> Int64Index: 1000 voci, da 0 a 999 Colonne dati: BodyMarkdown 1000 codeopere non null , ma quando faccio dataframe.head () riappaiono i vecchi nomi per le colonne.
darKoram,

12
Ottengo il temuto SettingWithCopyWarning:quando uso il secondo frammento di codice in questa risposta.
Monica Heddneck,

esiste una versione di questo con sostituzione regex?
denfromufa,

@lexual Cosa succede se due colonne esistenti hanno lo stesso nome? Come faccio a fare riferimento al vecchio nome di colonna?
vagabondo

14
La prima soluzione: df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})modifica il nome visualizzato, ma non gli elementi nella struttura dati sottostante. Quindi, se provi df['newName1'], otterrai un errore. Il inplace=Trueè necessario per evitare che Gotchya.
irritable_phd_syndrom,

402

Il renamemetodo può assumere una funzione , ad esempio:

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)

56
Bello. Questo mi ha salvato la giornata:df.rename(columns=lambda x: x.lstrip(), inplace=True)
root-11,

2
Simile a @ root-11 - nel mio caso c'era un carattere punto elenco che non era stampato nell'output della console IPython, quindi dovevo rimuovere più di uno spazio bianco (striscia), quindi:t.columns = t.columns.str.replace(r'[^\x00-\x7F]+','')
The Red Pea,

9
df.rename(columns=lambda x: x.replace(' ', '_'), inplace=True)è un gioiello in modo che possiamo scrivere df.Column_1_Nameinvece di scrivere df.loc[:, 'Column 1 Name'].
Tavolini Bobby il


164

Panda 0,21+ Risposta

Ci sono stati alcuni aggiornamenti significativi alla ridenominazione delle colonne nella versione 0.21.

  • Il renamemetodo ha aggiunto il axisparametro che può essere impostato su columnso 1. Questo aggiornamento fa corrispondere questo metodo al resto dell'API panda. Ha ancora i parametri indexe columnsma non sei più costretto a usarli.
  • Il set_axismetodo con il inplaceset Falseconsente di rinominare tutte le etichette di indice o colonna con un elenco.

Esempi per Panda 0.21+

Costruire DataFrame campione:

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

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

Usando renamecon axis='columns'oaxis=1

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis='columns')

o

df.rename({'$a':'a', '$b':'b', '$c':'c', '$d':'d', '$e':'e'}, axis=1)

Entrambi si traducono in quanto segue:

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

È ancora possibile utilizzare la vecchia firma del metodo:

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

La renamefunzione accetta anche funzioni che verranno applicate al nome di ogni colonna.

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

o

df.rename(lambda x: x[1:], axis=1)

Usando set_axiscon un elenco einplace=False

È possibile fornire un elenco al set_axismetodo uguale in lunghezza al numero di colonne (o indice). Attualmente, per inplaceimpostazione predefinita è True, ma inplaceverrà impostato automaticamente Falsenelle versioni future.

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis='columns', inplace=False)

o

df.set_axis(['a', 'b', 'c', 'd', 'e'], axis=1, inplace=False)

Perché non usare df.columns = ['a', 'b', 'c', 'd', 'e']?

Non c'è niente di sbagliato nell'assegnare le colonne direttamente in questo modo. È una soluzione perfettamente valida.

Il vantaggio dell'utilizzo set_axisè che può essere utilizzato come parte di una catena di metodi e che restituisce una nuova copia di DataFrame. Senza di essa, dovresti archiviare i tuoi passaggi intermedi della catena in un'altra variabile prima di riassegnare le colonne.

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

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

1
Grazie per la Pandas 0.21+ answer- in qualche modo ho perso quella parte nella parte "novità" ...
MaxU

1
La soluzione non sembra funzionare per Pandas 3.6: df.rename ({'$ a': 'a', '$ b': 'b', '$ c': 'c', '$ d': 'd ',' $ e ':' e '}, axis =' colonne '). Ottiene un argomento inaspettato per la parola chiave "axis"
Arthur D. Howland,

3
df.columns = ['a', 'b', 'c', 'd', 'e'] sembra non funzionare più, lavorando con la versione 0.22 Ho un avviso che dice che Pandas non consente la creazione di colonne tramite un nuovo nome di attributo . come rinominare se tutte le mie colonne sono chiamate uguali: /
Nabla

C'è un modo per rinominare una, più o tutte le colonne, se non si conosce in anticipo il nome delle colonne ma solo il loro indice? Grazie!
tommy.carstensen,

questo è stato un commento molto utile. per esempio, la funzione lambda ha risposto alla mia domanda su come fare quanto segue:(df .groupby(['page',pd.Grouper(key='date',freq='MS')])['clicks'].sum() .unstack(1) .rename(lambda x: x.strftime("%Y-%m"), axis='columns') )
measureallthethings

131

Poiché desideri rimuovere solo il segno $ in tutti i nomi di colonna, puoi semplicemente fare:

df = df.rename(columns=lambda x: x.replace('$', ''))

O

df.rename(columns=lambda x: x.replace('$', ''), inplace=True)

1
Questo non solo aiuta nel caso di OP, ma anche nei requisiti generici. Ad esempio: per dividere il nome di una colonna con un separatore e usarne una parte.
Deepak,


61
old_names = ['$a', '$b', '$c', '$d', '$e'] 
new_names = ['a', 'b', 'c', 'd', 'e']
df.rename(columns=dict(zip(old_names, new_names)), inplace=True)

In questo modo è possibile modificare manualmente il modo new_namesdesiderato. Funziona alla grande quando è necessario rinominare solo alcune colonne per correggere errori di ortografia, accenti, rimuovere caratteri speciali ecc.


1
Mi piace questo approccio, ma penso che df.columns = ['a', 'b', 'c', 'd', 'e']sia più semplice.
Christopher Pearson,

1
Mi piace questo metodo per comprimere nomi vecchi e nuovi. Possiamo usare df.columns.valuesper ottenere i vecchi nomi.
bkowshik,

1
Visualizzo la vista tabulare e copio le colonne in old_names. Copio l'array di requisiti in new_names. Quindi utilizzare dict (zip (old_names, new_names)) Soluzione molto elegante.
miticalcoder

Uso spesso sottoinsiemi di elenchi di qualcosa del tipo myList = list(df) myList[10:20]:, ecc., Quindi è perfetto.
Tim Gottgetreu,

È meglio prendere i vecchi nomi come suggerito da @bkowshik, quindi modificarli e reinserirli, ovvero namez = df.columns.valuesseguiti da alcune modifiche, quindi df.columns = namez.
pauljohn32,

34

Soluzioni a una linea o pipeline

Mi concentrerò su due cose:

  1. OP afferma chiaramente

    Ho i nomi delle colonne modificati memorizzati in un elenco, ma non so come sostituire i nomi delle colonne.

    Non voglio risolvere il problema di come sostituire '$'o eliminare il primo carattere da ciascuna intestazione di colonna. OP ha già fatto questo passaggio. Invece voglio concentrarmi sulla sostituzione columnsdell'oggetto esistente con uno nuovo dato un elenco di nomi di colonne di sostituzione.

  2. df.columns = newdove si newtrova l'elenco dei nomi delle nuove colonne è semplice come si arriva. Lo svantaggio di questo approccio è che richiede la modifica dell'attributo del frame di dati esistente columnse non è in linea. Mostrerò alcuni modi per eseguire ciò tramite pipelining senza modificare il dataframe esistente.


Installazione 1
Per concentrarsi sulla necessità di rinominare i nomi delle colonne di sostituzione con un elenco preesistente, creerò un nuovo frame di dati di esempio dfcon nomi di colonna iniziali e nomi di nuove colonne non correlati.

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

Soluzione 1
pd.DataFrame.rename

È già stato detto che se avessi un dizionario che mappasse i vecchi nomi di colonna con i nuovi nomi di colonna, potresti usare 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

Tuttavia, puoi facilmente creare quel dizionario e includerlo nella chiamata a rename. Quanto segue sfrutta il fatto che durante l'iterazione dfripetiamo il nome di ogni colonna.

# 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

Funziona alla grande se i nomi delle colonne originali sono univoci. Ma se non lo sono, allora questo si rompe.


Imposta 2
colonne non univoche

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

Soluzione 2
pd.concat usando l' keysargomento

Innanzitutto, nota cosa succede quando proviamo a utilizzare la soluzione 1:

df.rename(columns=dict(zip(df, new)))

   y765  y765  z432
0     1     3     5
1     2     4     6

Non abbiamo mappato l' newelenco come nomi di colonna. Abbiamo finito per ripetere y765. Invece, possiamo usare l' keysargomento della pd.concatfunzione mentre si scorre tra le colonne di df.

pd.concat([c for _, c in df.items()], axis=1, keys=new) 

   x098  y765  z432
0     1     3     5
1     2     4     6

Soluzione 3
Ricostruisci. Questo dovrebbe essere usato solo se ne hai uno singolo dtypeper tutte le colonne. Altrimenti, finirai con dtype objecttutte le colonne e convertirle indietro richiede più lavoro di dizionario.

singolo dtype

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

   x098  y765  z432
0     1     3     5
1     2     4     6

Misto 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

Soluzione 4
Questo è un trucco ingannevole con transposee set_index. pd.DataFrame.set_indexci consente di impostare un indice in linea ma non esiste un corrispondente set_columns. Quindi possiamo trasporre, quindi set_index, e trasporre indietro. Tuttavia, lo stesso singolo dtyperispetto al mistodtype avvertimento della soluzione 3 si applica qui.

singolo dtype

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

   x098  y765  z432
0     1     3     5
1     2     4     6

Misto 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

Soluzione 5
Usa a lambdain pd.DataFrame.renameche cicla attraverso ogni elemento di new
In questa soluzione, passiamo un lambda che prende xma poi lo ignora. Ci vuole anche un yma non se lo aspetta. Invece, un iteratore viene fornito come valore predefinito e posso quindi utilizzarlo per scorrere uno alla volta senza considerare quale sia il valore di x.

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

   x098  y765  z432
0     1     3     5
1     2     4     6

E come mi hanno indicato le persone nella chat di sopython , se aggiungo una via *di mezzo xe yposso proteggere la mia yvariabile. Tuttavia, in questo contesto, non credo che debba essere protetto. Vale ancora la pena menzionarlo.

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

   x098  y765  z432
0     1     3     5
1     2     4     6

Forse possiamo aggiungeredf.rename(lambda x : x.lstrip('$'),axis=1)
YOBEN_S

Ciao @piRSquared, saresti in grado di elaborare in che modo Panda utilizza la funzione lambda nella soluzione 5, per favore? Non seguo esattamente cosa intendi quando dici che xè ignorato?
Josmoor98,

33

Nomi delle colonne e nomi delle serie

Vorrei spiegare un po 'cosa succede dietro le quinte.

I frame di dati sono un set di serie.

Le serie a loro volta sono un'estensione di a numpy.array

numpy.arrays hanno una proprietà .name

Questo è il nome della serie. È raro che i panda rispettino questo attributo, ma permane in alcuni punti e può essere usato per hackerare alcuni comportamenti dei panda.

Denominazione dell'elenco di colonne

Molte risposte qui parlano df.columnsdell'attributo a listquando in realtà è a Series. Ciò significa che ha un .nameattributo.

Questo è ciò che accade se decidi di inserire il nome delle colonne Series:

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

Si noti che il nome dell'indice viene sempre inferiore di una colonna.

Manufatti che persistono

L' .nameattributo persiste a volte. Se si imposta, df.columns = ['one', 'two']allora df.one.namesarà 'one'.

Se si imposta df.one.name = 'three'quindi df.columnsti darà ancora ['one', 'two'], edf.one.name ti darà'three'

MA

pd.DataFrame(df.one) tornerà

    three
0       1
1       2
2       3

Perché i panda riutilizzano .namequelli già definiti Series.

Nomi delle colonne a più livelli

Panda ha modi di fare nomi di colonne a più livelli. Non c'è così tanta magia in gioco, ma ho voluto coprire anche questo nella mia risposta poiché non vedo nessuno raccoglierlo qui.

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

Ciò è facilmente realizzabile impostando le colonne sugli elenchi, in questo modo:

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

18

Se hai il frame di dati, df.columns scarica tutto in un elenco che puoi manipolare e quindi riassegna nel tuo frame di dati come i nomi delle colonne ...

columns = df.columns
columns = [row.replace("$","") for row in columns]
df.rename(columns=dict(zip(columns, things)), inplace=True)
df.head() #to validate the output

Miglior modo? IDK. Un modo - sì.

Un modo migliore per valutare tutte le principali tecniche avanzate nelle risposte alla domanda è di seguito usando cProfile per misurare la memoria e i tempi di esecuzione. @kadee, @kaitlyn e @eumiro avevano le funzioni con i tempi di esecuzione più rapidi, anche se queste funzioni sono così veloci che stiamo confrontando l'arrotondamento di .000 e .001 secondi per tutte le risposte. Morale: la mia risposta sopra probabilmente non è il modo "migliore".

import pandas as pd
import cProfile, pstats, re

old_names = ['$a', '$b', '$c', '$d', '$e']
new_names = ['a', 'b', 'c', 'd', 'e']
col_dict = {'$a': 'a', '$b': 'b','$c':'c','$d':'d','$e':'e'}

df = pd.DataFrame({'$a':[1,2], '$b': [10,20],'$c':['bleep','blorp'],'$d':[1,2],'$e':['texa$','']})

df.head()

def eumiro(df,nn):
    df.columns = nn
    #This direct renaming approach is duplicated in methodology in several other answers: 
    return df

def lexual1(df):
    return df.rename(columns=col_dict)

def lexual2(df,col_dict):
    return df.rename(columns=col_dict, inplace=True)

def Panda_Master_Hayden(df):
    return df.rename(columns=lambda x: x[1:], inplace=True)

def paulo1(df):
    return df.rename(columns=lambda x: x.replace('$', ''))

def paulo2(df):
    return df.rename(columns=lambda x: x.replace('$', ''), inplace=True)

def migloo(df,on,nn):
    return df.rename(columns=dict(zip(on, nn)), inplace=True)

def kadee(df):
    return df.columns.str.replace('$','')

def awo(df):
    columns = df.columns
    columns = [row.replace("$","") for row in columns]
    return df.rename(columns=dict(zip(columns, '')), inplace=True)

def kaitlyn(df):
    df.columns = [col.strip('$') for col in df.columns]
    return df

print 'eumiro'
cProfile.run('eumiro(df,new_names)')
print 'lexual1'
cProfile.run('lexual1(df)')
print 'lexual2'
cProfile.run('lexual2(df,col_dict)')
print 'andy hayden'
cProfile.run('Panda_Master_Hayden(df)')
print 'paulo1'
cProfile.run('paulo1(df)')
print 'paulo2'
cProfile.run('paulo2(df)')
print 'migloo'
cProfile.run('migloo(df,old_names,new_names)')
print 'kadee'
cProfile.run('kadee(df)')
print 'awo'
cProfile.run('awo(df)')
print 'kaitlyn'
cProfile.run('kaitlyn(df)')

Perché hai bisogno di rinominare il metodo? Qualcosa del genere ha funzionato per me # df.columns = [row.replace ('$', '') per la riga in df.columns]
shantanuo,

Non capisco la parte delle "cose". Cosa devo sostituire? Le vecchie colonne?
Andrea Ianni ௫

18

Diciamo che questo è il tuo dataframe.

inserisci qui la descrizione dell'immagine

Puoi rinominare le colonne usando due metodi.

  1. utilizzando dataframe.columns=[#list]

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

    inserisci qui la descrizione dell'immagine

    La limitazione di questo metodo è che se si deve modificare una colonna, è necessario passare l'elenco completo delle colonne. Inoltre, questo metodo non è applicabile sulle etichette degli indici. Ad esempio, se hai superato questo:

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

    Questo genererà un errore. Mancata corrispondenza della lunghezza: l'asse previsto ha 5 elementi, i nuovi valori hanno 4 elementi.

  2. Un altro metodo è il rename()metodo Pandas che viene utilizzato per rinominare qualsiasi indice, colonna o riga

    df = df.rename(columns={'$a':'a'})

    inserisci qui la descrizione dell'immagine

Allo stesso modo, è possibile modificare qualsiasi riga o colonna.


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

Se il tuo nuovo elenco di colonne è nello stesso ordine delle colonne esistenti, l'assegnazione è semplice:

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

Se avevi un dizionario digitato sui vecchi nomi di colonna con i nuovi nomi di colonna, puoi fare quanto segue:

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

Se non si dispone di un elenco o di una mappatura del dizionario, è possibile rimuovere il $simbolo principale tramite una comprensione dell'elenco:

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

2
Invece di lambda col: d[col]te potresti passare d.get... così sembrerebbedf.columns.map(d.get)
piRSquared il


15

Comprendiamo la ridenominazione con un piccolo esempio ...

1. Rinominare le colonne usando la mappatura:

df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6]}) #creating a df with column name A and B
df.rename({"A": "new_a", "B": "new_b"},axis='columns',inplace =True) #renaming column A with 'new_a' and B with 'new_b'

output:
   new_a  new_b
0  1       4
1  2       5
2  3       6

2. Rinominare l'indice / Row_Name usando il mapping:

df.rename({0: "x", 1: "y", 2: "z"},axis='index',inplace =True) #Row name are getting replaced by 'x','y','z'.

output:
       new_a  new_b
    x  1       4
    y  2       5
    z  3       6

La risposta più votata ha già esempi del genere ...
Itamar Mushkin l'

14

Un altro modo in cui possiamo sostituire le etichette delle colonne originali è quello di rimuovere i caratteri indesiderati (qui '$') dalle etichette delle colonne originali.

Ciò avrebbe potuto essere eseguito eseguendo un ciclo for su df.columns e aggiungendo le colonne rimosse a df.columns.

Invece, possiamo farlo ordinatamente in una singola istruzione usando la comprensione dell'elenco come di seguito:

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

(il stripmetodo in Python rimuove il carattere dato dall'inizio e dalla fine della stringa.)


2
Puoi spiegare come / perché funziona? Ciò renderà la risposta più preziosa per i futuri lettori.
Dan Lowe,

12

Davvero semplice da usare

df.columns = ['Name1', 'Name2', 'Name3'...]

e assegnerà i nomi delle colonne in base all'ordine in cui li hai inseriti


10

Puoi usare str.sliceper quello:

df.columns = df.columns.str.slice(1)

1
PS: Questo è un equivalente più dettagliato di df.columns.str[1:]... probabilmente meglio usarlo, è più breve e più ovvio.
cs95,

9

Conosco questa domanda e la risposta è stata masticata a morte. Ma ho fatto riferimento ad esso per l'ispirazione per uno dei problemi che stavo avendo. Sono stato in grado di risolverlo usando frammenti di risposte diverse, fornendo così la mia risposta nel caso qualcuno ne avesse bisogno.

Il mio metodo è generico in cui è possibile aggiungere ulteriori delimitatori separando la virgola delimiters= variabili e rendendola a prova di futuro.

Codice di lavoro:

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 ]

Produzione:

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

8

Si noti che questo approccio non funziona per un MultiIndex. Per un MultiIndex, devi fare qualcosa del tipo:

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

8

Un'altra opzione è quella di rinominare usando un'espressione regolare:

import pandas as pd
import re

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

df = df.rename(columns=lambda x: re.sub('\$','',x))
>>> df
   a  b  c
0  1  3  5
1  2  4  6

6

Se hai a che fare con un sacco di colonne nominate dal sistema di fornitura fuori dal tuo controllo, ho trovato il seguente approccio che è una combinazione di un approccio generale e sostituzioni specifiche in una volta sola.

Innanzitutto creare un dizionario dai nomi delle colonne del frame di dati utilizzando le espressioni regex per eliminare alcune appendici dei nomi delle colonne e quindi aggiungere sostituzioni specifiche al dizionario per denominare le colonne principali come previsto più avanti nel database di ricezione.

Questo viene quindi applicato al frame di dati in una volta sola.

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)

5

Oltre alla soluzione già fornita, è possibile sostituire tutte le colonne durante la lettura del file. Possiamo usare nameseheader=0 per farlo.

Innanzitutto, creiamo un elenco dei nomi che ci piace usare come nomi delle nostre colonne:

import pandas as pd

ufo_cols = ['city', 'color reported', 'shape reported', 'state', 'time']
ufo.columns = ufo_cols

ufo = pd.read_csv('link to the file you are using', names = ufo_cols, header = 0)

In questo caso, tutti i nomi delle colonne verranno sostituiti con i nomi presenti nell'elenco.


4

Ecco una piccola funzione che mi piace usare per ridurre la digitazione:

def rename(data, oldnames, newname): 
    if type(oldnames) == str: #input can be a string or list of strings 
        oldnames = [oldnames] #when renaming multiple columns 
        newname = [newname] #make sure you pass the corresponding list of new names
    i = 0 
    for name in oldnames:
        oldvar = [c for c in data.columns if name in c]
        if len(oldvar) == 0: 
            raise ValueError("Sorry, couldn't find that column in the dataset")
        if len(oldvar) > 1: #doesn't have to be an exact match 
            print("Found multiple columns that matched " + str(name) + " :")
            for c in oldvar:
                print(str(oldvar.index(c)) + ": " + str(c))
            ind = input('please enter the index of the column you would like to rename: ')
            oldvar = oldvar[int(ind)]
        if len(oldvar) == 1:
            oldvar = oldvar[0]
        data = data.rename(columns = {oldvar : newname[i]})
        i += 1 
    return data   

Ecco un esempio di come funziona:

In [2]: df = pd.DataFrame(np.random.randint(0,10,size=(10, 4)), columns=['col1','col2','omg','idk'])
#first list = existing variables
#second list = new names for those variables
In [3]: df = rename(df, ['col','omg'],['first','ohmy']) 
Found multiple columns that matched col :
0: col1
1: col2

please enter the index of the column you would like to rename: 0

In [4]: df.columns
Out[5]: Index(['first', 'col2', 'ohmy', 'idk'], dtype='object')

1
Il caso d'uso di una funzione come questa è estremamente raro. Nella maggior parte dei casi, so cosa sto cercando e in cosa voglio rinominarlo, lo assegnerei / modificherei da solo.
cs95,

1
@ cs95 Tendo a lavorare con grandi sondaggi nazionali o internazionali in cui le variabili avranno nomi di variabili codificati che iniziano con prefissi a seconda delle opzioni di risposta, scale di likert e ramificazione (come EDU_2913.443, EDU_2913.421, ...). Questa funzione è stata molto utile per me nel lavorare con questi tipi di set, capisco se non è per te :)
Seeiespi,

4

Rinominare le colonne nei panda è un compito facile.

df.rename(columns = {'$a':'a','$b':'b','$c':'c','$d':'d','$e':'e'},inplace = True)

2

Supponendo che tu possa usare l'espressione regolare. Questa soluzione elimina la necessità della codifica manuale mediante regex

import pandas as pd
import re

srch=re.compile(r"\w+")

data=pd.read_csv("CSV_FILE.csv")
cols=data.columns
new_cols=list(map(lambda v:v.group(),(list(map(srch.search,cols)))))
data.columns=new_cols

2
È buona norma su Stack Overflow aggiungere una spiegazione del perché la soluzione dovrebbe funzionare o è migliore delle soluzioni esistenti. Per maggiori informazioni leggi Come rispondere .
Samuel Liew

Notate come la risposta più votata richiede una qualche forma di hard coding e la risposta peggiore richiede solo un approccio descrittivo e procedurale?
Kaustubh J

Esistono soluzioni migliori (più leggibili) che utilizzano anche regex. Questo sta facendo molto più di quanto dovrebbe per una semplice operazione di ridenominazione. C'è anche il pericolo che il modello non corrisponda a nulla, nel qual caso non hai fatto nulla per gestire gli errori.
cs95,
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.