Renombrar columnas en pandas


1829

Tengo un DataFrame que usa pandas y etiquetas de columna que necesito editar para reemplazar las etiquetas de columna originales.

Me gustaría cambiar los nombres de columna en un DataFrame Adonde están los nombres de columna originales:

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

a

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

Tengo los nombres de columna editados almacenados en una lista, pero no sé cómo reemplazar los nombres de columna.


1
Es posible que desee consultar los documentos oficiales que cubren las etiquetas de las columnas de cambio de nombre: pandas.pydata.org/pandas-docs/stable/user_guide/text.html
ccpizza

Respuestas:


1831

Simplemente asígnelo al .columnsatributo:

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

303
¿Es posible cambiar el nombre del encabezado de una sola columna?
ericmjl

112
@ericmjl: suponga que desea cambiar el nombre de la primera variable de df. Entonces puede hacer algo como:new_columns = df.columns.values; new_columns[0] = 'XX'; df.columns = new_columns
cd98

54
Parece que podría haber hecho simplemente df.columns.values ​​[0] = 'XX'
RAYO

25
Es broma, @RAY, no hagas eso. Parece que es una lista generada independientemente de cualquier indexación que almacene el nombre de la columna. Hace un buen trabajo destruyendo nombres de columnas para tu df ...
Mitch Flax

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

2848

RENOMBRAR COLUMNAS ESPECÍFICAS

Use la df.rename()función y refiera las columnas a renombrar. No todas las columnas deben ser renombradas:

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)

Ejemplo de código mínimo

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

Los siguientes métodos funcionan y producen el mismo resultado:

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

Recuerde asignar el resultado nuevamente, ya que la modificación no está en su lugar. Alternativamente, especifique 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

Desde v0.25, también puede especificar errors='raise'generar errores si se especifica una columna para cambiar el nombre no válida. Ver v0.25 rename()documentos .


REASIGNAR CABEZALES DE COLUMNA

Use df.set_axis()con axis=1y inplace=False(para devolver 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

Esto devuelve una copia, pero puede modificar el DataFrame in situ configurando inplace=True (este es el comportamiento predeterminado para las versiones <= 0.24, pero es probable que cambie en el futuro).

También puede asignar encabezados directamente:

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
cuando hago esto con un marco de datos de 6 columnas (marco de datos <presione enter>) la representación abreviada: code<clase 'pandas.core.frame.DataFrame'> Int64Index: 1000 entradas, 0 a 999 columnas de datos: BodyMarkdown 1000 codetrabajos no nulos , pero cuando hago dataframe.head (), los nombres antiguos de las columnas vuelven a aparecer.
darKoram

12
Me da miedo SettingWithCopyWarning:cuando uso el segundo fragmento de código en esta respuesta.
Monica Heddneck

¿Hay una versión de esto con reemplazo de expresiones regulares?
denfromufa

@lexual ¿Qué sucede si dos columnas existentes tienen el mismo nombre? ¿Cómo me refiero al antiguo nombre de columna?
vagabundo

14
La primera solución: df = df.rename(columns={'oldName1': 'newName1', 'oldName2': 'newName2'})cambia el nombre que se muestra, pero no los elementos en la estructura de datos subyacente. Entonces, si lo intentas df['newName1'], obtendrás un error. El inplace=Truees necesario para evitar ese gotchya.
irritable_phd_syndrom

402

El renamemétodo puede tomar una función , por ejemplo:

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
Agradable. Este me salvó el día:df.rename(columns=lambda x: x.lstrip(), inplace=True)
root-11

2
Similar a @ root-11: en mi caso, había un carácter de viñeta que no se imprimió en la salida de la consola IPython, por lo que necesitaba eliminar más que solo espacios en blanco (stripe), por lo que:t.columns = t.columns.str.replace(r'[^\x00-\x7F]+','')
The Red Pea el

99
df.rename(columns=lambda x: x.replace(' ', '_'), inplace=True)es una joya para que podamos escribir en df.Column_1_Namelugar de escribir df.loc[:, 'Column 1 Name'].
Little Bobby Tables


164

Pandas 0.21+ Respuesta

Ha habido algunas actualizaciones significativas para cambiar el nombre de la columna en la versión 0.21.

  • El renamemétodo ha agregado el axisparámetro que se puede establecer en columnso 1. Esta actualización hace que este método coincida con el resto de la API de pandas. Todavía tiene el indexycolumns parámetros pero ya no estás obligado a usarlos.
  • El set_axismétodo con el inplaceconjunto para le Falsepermite cambiar el nombre de todas las etiquetas de índice o columna con una lista.

Ejemplos para Pandas 0.21+

Construya el DataFrame de muestra:

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

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

Ambos resultan en lo siguiente:

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

Todavía es posible usar la firma del método anterior:

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

La renamefunción también acepta funciones que se aplicarán a cada nombre de columna.

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

o

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

Usando set_axiscon una lista yinplace=False

Puede proporcionar una lista al set_axismétodo que tenga la misma longitud que el número de columnas (o índice). Actualmente, el valor inplacepredeterminado es True, pero inplaceserá predeterminado Falseen versiones futuras.

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)

¿Por qué no usar df.columns = ['a', 'b', 'c', 'd', 'e'] ?

No hay nada de malo en asignar columnas directamente como esta. Es una solución perfectamente buena.

La ventaja de usar set_axises que se puede usar como parte de una cadena de métodos y que devuelve una nueva copia del DataFrame. Sin él, tendría que almacenar sus pasos intermedios de la cadena en otra variable antes de reasignar las columnas.

# 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
Gracias por el Pandas 0.21+ answer- de alguna manera me perdí esa parte en la parte de "lo nuevo" ...
MaxU

1
La solución no parece funcionar para Pandas 3.6: df.rename ({'$ a': 'a', '$ b': 'b', '$ c': 'c', '$ d': 'd ',' $ e ':' e '}, axis =' columnas '). Obtiene un argumento de palabra clave inesperado "axis"
Arthur D. Howland

3
df.columns = ['a', 'b', 'c', 'd', 'e'] parece que ya no funciona, trabajando con la versión 0.22 Tengo una advertencia que dice que Pandas no permite que se creen columnas a través de Un nuevo nombre de atributo . cómo cambiar el nombre si todas mis columnas se llaman igual: /
Nabla

¿Hay alguna manera de cambiar el nombre de una, varias o todas las columnas, si no conoce el nombre de la (s) columna (s) de antemano sino solo su índice? ¡Gracias!
tommy.carstensen

Este fue un comentario muy útil. por ejemplo, la función lambda respondió a mi pregunta sobre cómo hacer lo siguiente:(df .groupby(['page',pd.Grouper(key='date',freq='MS')])['clicks'].sum() .unstack(1) .rename(lambda x: x.strftime("%Y-%m"), axis='columns') )
medir todas

131

Como solo desea eliminar el signo $ en todos los nombres de columna, puede hacer lo siguiente:

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

O

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

1
Este no solo ayuda en el caso de OP, sino también en los requisitos genéricos. Por ejemplo: para dividir un nombre de columna por un separador y usar una parte de él.
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)

De esta manera, puede editar manualmente new_nameslo que desee. Funciona muy bien cuando necesita cambiar el nombre de unas pocas columnas para corregir errores ortográficos, acentos, eliminar caracteres especiales, etc.


1
Me gusta este enfoque, pero creo que df.columns = ['a', 'b', 'c', 'd', 'e']es más simple.
Christopher Pearson

1
Me gusta este método de comprimir nombres antiguos y nuevos. Podemos usar df.columns.valuespara obtener los nombres antiguos.
bkowshik

1
Muestro la vista tabular y copio las columnas a old_names. Copio la matriz de requisitos a new_names. Luego use dict (zip (old_names, new_names)) Solución muy elegante.
mythicalcoder

A menudo uso subconjuntos de listas de algo como:, myList = list(df) myList[10:20]etc., así que esto es perfecto.
Tim Gottgetreu

Lo mejor es tomar los nombres antiguos como sugirió @bkowshik, luego editarlos y volver a insertarlos, es decir, namez = df.columns.valuesseguido de algunas modificaciones df.columns = namez.
pauljohn32

34

Soluciones de una línea o tubería

Me enfocaré en dos cosas:

  1. OP establece claramente

    Tengo los nombres de columna editados almacenados en una lista, pero no sé cómo reemplazar los nombres de columna.

    No quiero resolver el problema de cómo reemplazar '$'o quitar el primer carácter de cada encabezado de columna. OP ya ha hecho este paso. En cambio, quiero centrarme en reemplazar el columnsobjeto existente con uno nuevo dada una lista de nombres de columnas de reemplazo.

  2. df.columns = newdonde newestá la lista de nuevos nombres de columnas es tan simple como parece. El inconveniente de este enfoque es que requiere editar el columnsatributo del marco de datos existente y no se hace en línea. Mostraré algunas formas de realizar esto mediante la canalización sin editar el marco de datos existente.


Configuración 1
Para centrarnos en la necesidad de cambiar el nombre de los nombres de las columnas de reemplazo por una lista preexistente, crearé un nuevo marco de datos de muestra dfcon nombres de columnas iniciales y nombres de columnas nuevos no relacionados.

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

Solución 1
pd.DataFrame.rename

Ya se ha dicho que si tuviera un diccionario que asignara los nombres de las columnas antiguas a los nuevos, podría usarlo 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

Sin embargo, puede crear fácilmente ese diccionario e incluirlo en la llamada a rename. Lo siguiente aprovecha el hecho de que cuando iteramos df, iteramos sobre cada nombre de columna.

# 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

Esto funciona muy bien si los nombres de columna originales son únicos. Pero si no lo son, entonces esto se rompe.


Configurar 2
columnas no únicas

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

Solución 2
pd.concat usando el keysargumento

Primero, observe lo que sucede cuando intentamos usar la solución 1:

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

   y765  y765  z432
0     1     3     5
1     2     4     6

No mapeamos la newlista como los nombres de las columnas. Terminamos repitiendo y765. En cambio, podemos usar el keysargumento de la pd.concatfunción mientras iteramos a través de las columnas de df.

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

   x098  y765  z432
0     1     3     5
1     2     4     6

Solución 3
Reconstruir. Esto solo debe usarse si tiene un solo dtypepara todas las columnas. De lo contrario, terminará con dtype objecttodas las columnas y convertirlas de nuevo requiere más trabajo de diccionario.

Soltero dtype

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

   x098  y765  z432
0     1     3     5
1     2     4     6

Mezclado 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

Solución 4
Este es un truco ingenioso con transposey set_index. pd.DataFrame.set_indexnos permite establecer un índice en línea pero no hay correspondencia correspondiente set_columns. Entonces podemos transponer, entonces set_index, y volver a transponer. Sin embargo, la misma advertencia simple dtypeversus mixta dtypede la solución 3 se aplica aquí.

Soltero dtype

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

   x098  y765  z432
0     1     3     5
1     2     4     6

Mezclado 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

Solución 5
Use a lambdaen pd.DataFrame.renameese ciclo a través de cada elemento de new
En esta solución, pasamos una lambda que toma xpero luego la ignora. También toma un ypero no lo espera. En cambio, se proporciona un iterador como valor predeterminado y luego puedo usarlo para recorrer uno a la vez sin tener en cuenta cuál es el valor de x.

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

   x098  y765  z432
0     1     3     5
1     2     4     6

Y como me señaló la gente en el chat de sopython , si agrego un *intermedio xy ypuedo proteger mi yvariable. Sin embargo, en este contexto, no creo que necesite protección. Todavía vale la pena mencionarlo.

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

   x098  y765  z432
0     1     3     5
1     2     4     6

Tal vez podamos agregardf.rename(lambda x : x.lstrip('$'),axis=1)
YOBEN_S

Hola @piRSquared, ¿podría explicar cómo los pandas usan la función lambda en la Solución 5, por favor? ¿No entiendo lo que quieres decir cuando dices que xse ignora?
Josmoor98

33

Nombres de columna versus nombres de series

Me gustaría explicar un poco lo que sucede detrás de escena.

Los marcos de datos son un conjunto de series.

Las series a su vez son una extensión de un numpy.array

numpy.arrays tiene una propiedad .name

Este es el nombre de la serie. Rara vez los pandas respetan este atributo, pero persiste en algunos lugares y puede usarse para piratear algunos comportamientos de los pandas.

Nombrar la lista de columnas

Muchas respuestas aquí hablan de que el df.columnsatributo es un listcuando, de hecho, es un Series. Esto significa que tiene un .nameatributo.

Esto es lo que sucede si decide completar el nombre de las columnas 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

Tenga en cuenta que el nombre del índice siempre viene una columna más abajo.

Artefactos que permanecen

El .nameatributo persiste a veces. Si establece, df.columns = ['one', 'two']entonces df.one.nameserá 'one'.

Si se establece df.one.name = 'three'a continuación, df.columnstodavía le dará ['one', 'two'], y df.one.namele dará'three'

PERO

pd.DataFrame(df.one) volverá

    three
0       1
1       2
2       3

Porque los pandas reutilizan los .namede lo ya definido Series.

Nombres de columna de niveles múltiples

Pandas tiene formas de hacer nombres de columnas de varias capas. No hay tanta magia involucrada, pero también quería cubrir esto en mi respuesta, ya que no veo a nadie entendiendo esto aquí.

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

Esto se puede lograr fácilmente configurando columnas en listas, como esta:

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

18

Si tiene el marco de datos, df.columns volca todo en una lista que puede manipular y luego reasignar en su marco de datos como los nombres de las columnas ...

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

¿Mejor manera? NO SÉ. Un camino, sí.

A continuación se muestra una mejor manera de evaluar todas las técnicas principales presentadas en las respuestas a la pregunta utilizando cProfile para medir la memoria y el tiempo de ejecución. @kadee, @kaitlyn y @eumiro tenían las funciones con los tiempos de ejecución más rápidos, aunque estas funciones son tan rápidas que estamos comparando el redondeo de .000 y .001 segundos para todas las respuestas. Moraleja: mi respuesta anterior probablemente no sea la mejor manera.

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

¿Por qué necesitas cambiar el nombre del método? Algo como esto funcionó para mí # df.columns = [row.replace ('$', '') para la fila en df.columns]
shantanuo

No entiendo la parte de 'cosas'. ¿Qué tengo que sustituir? Las viejas columnas?
Andrea Ianni ௫

18

Digamos que este es su marco de datos.

ingrese la descripción de la imagen aquí

Puede cambiar el nombre de las columnas con dos métodos.

  1. Utilizando dataframe.columns=[#list]

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

    ingrese la descripción de la imagen aquí

    La limitación de este método es que si se debe cambiar una columna, se debe pasar la lista completa de columnas. Además, este método no es aplicable en las etiquetas de índice. Por ejemplo, si pasó esto:

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

    Esto arrojará un error. Longitud no coincidente: el eje esperado tiene 5 elementos, los nuevos valores tienen 4 elementos.

  2. Otro método es el rename()método Pandas , que se utiliza para cambiar el nombre de cualquier índice, columna o fila.

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

    ingrese la descripción de la imagen aquí

Del mismo modo, puede cambiar cualquier fila o columna.


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

Si su nueva lista de columnas está en el mismo orden que las columnas existentes, la asignación es simple:

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

Si tuviera un diccionario tecleado en los nombres de columnas antiguas a los nombres de columnas nuevas, podría hacer lo siguiente:

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

Si no tiene una lista o un mapeo de diccionario, puede quitar el $símbolo inicial a través de una comprensión de la lista:

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

2
En lugar de lambda col: d[col]que pudieras pasar d.get... así seríadf.columns.map(d.get)
piRSquared


15

Comprendamos el cambio de nombre con un pequeño ejemplo ...

1. Renombrar columnas usando mapeo:

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. Cambiar el nombre del índice / Row_Name usando la asignación:

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 respuesta más votada ya tiene esos ejemplos ...
Itamar Mushkin

14

Otra forma en que podríamos reemplazar las etiquetas de columna originales es quitando los caracteres no deseados (aquí '$') de las etiquetas de columna originales.

Esto podría haberse hecho ejecutando un bucle for sobre df.columns y agregando las columnas despojadas a df.columns.

En cambio, podemos hacer esto ordenadamente en una sola declaración usando la comprensión de la lista como a continuación:

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

(El stripmétodo en Python elimina el carácter dado desde el principio y el final de la cadena).


2
¿Puedes explicar cómo / por qué funciona esto? Eso hará que la respuesta sea más valiosa para los futuros lectores.
Dan Lowe

12

Realmente simple solo use

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

y asignará los nombres de columna por el orden en que los colocó


10

Podrías usar str.slicepara eso:

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

1
PD: Este es un equivalente más detallado de df.columns.str[1:]... probablemente mejor usar eso, es más corto y más obvio.
cs95

9

Sé que esta pregunta y respuesta han sido masticadas hasta la muerte. Pero me referí a él como inspiración para uno de los problemas que estaba teniendo. Pude resolverlo usando fragmentos de diferentes respuestas, por lo tanto, proporcioné mi respuesta en caso de que alguien la necesite.

Mi método es genérico en el que puede agregar delimitadores adicionales separando la delimiters=variable de la coma y preparándolo para el futuro.

Código de trabajo

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 ]

Salida:

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

Tenga en cuenta que este enfoque no funciona para un MultiIndex. Para un MultiIndex, debe hacer algo como lo siguiente:

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

Otra opción es renombrar usando una expresión regular:

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

Si tiene que lidiar con un montón de columnas nombradas por el sistema proveedor fuera de su control, se me ocurrió el siguiente enfoque que es una combinación de un enfoque general y reemplazos específicos de una sola vez.

Primero cree un diccionario a partir de los nombres de columna del marco de datos utilizando expresiones de expresiones regulares para descartar ciertos apéndices de nombres de columna y luego agregue reemplazos específicos al diccionario para nombrar columnas centrales como se espera más adelante en la base de datos receptora.

Esto se aplica al marco de datos de una vez.

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

Además de la solución ya proporcionada, puede reemplazar todas las columnas mientras lee el archivo. Podemos usar namesyheader=0 para hacer eso.

Primero, creamos una lista de los nombres que nos gusta usar como nuestros nombres de columna:

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)

En este caso, todos los nombres de columna serán reemplazados por los nombres que tiene en su lista.


4

Aquí hay una pequeña función ingeniosa que me gusta usar para reducir la escritura:

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   

Aquí hay un ejemplo de cómo funciona:

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
El caso de uso para una función como esta es extremadamente raro. En la mayoría de los casos, sé lo que estoy buscando y a qué quiero cambiarle el nombre, solo lo asignaría / modificaría yo mismo.
cs95

1
@ cs95 Tiendo a trabajar con grandes encuestas nacionales o internacionales en las que las variables tendrán nombres de variables codificados que comienzan con prefijos dependiendo de las opciones de respuesta, escalas likert y ramificaciones (como EDU_2913.443, EDU_2913.421, ...). Esta función me ha sido muy útil para trabajar con ese tipo de conjuntos, aunque entiendo que no sea para ti :)
seeiespi

4

Renombrar columnas en pandas es una tarea fácil.

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

2

Asumiendo que puedes usar expresiones regulares. Esta solución elimina la necesidad de codificación manual utilizando expresiones regulares.

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
Es una buena práctica en Stack Overflow agregar una explicación de por qué su solución debería funcionar o es mejor que las soluciones existentes. Para obtener más información, lea Cómo responder .
Samuel Liew

¿Observa cómo la respuesta mejor calificada requiere algún tipo de codificación rígida y la respuesta peor calificada requiere solo un enfoque descriptivo y de procedimiento?
Kaustubh J

Hay mejores soluciones (más legibles) que también utilizan expresiones regulares que esto. Esto está haciendo mucho más de lo que debería para una simple operación de cambio de nombre. También existe el peligro de que el patrón no coincida con nada, en cuyo caso no ha hecho nada para manejar los errores.
cs95
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.