una renombrar one libreria index eliminar data crear columnas columna column borrar agregar python pandas replace dataframe rename

python - renombrar - Renombrando columnas en pandas



pandas rename one column (28)

DataFrame - df.rename () funcionará.

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

df es el DataFrame que tiene, y el Nombre antiguo es el nombre de la columna que desea cambiar, luego el Nombre nuevo es el nuevo nombre al que cambia. Este método incorporado de DataFrame hace que las cosas sean más fáciles.

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 A donde los nombres de columna originales son:

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

a

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

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


Nombres de columnas vs 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.array s tiene una propiedad .name

Este es el nombre de la serie. Raras veces los pandas respetan este atributo, pero permanece en algunos lugares y se puede usar para piratear algunos comportamientos de pandas.

Nombrando la lista de columnas

Muchas respuestas aquí hablan de que el atributo df.columns es una list cuando en realidad es una Series . Esto significa que tiene un atributo .name .

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 aparece una columna más abajo.

Artefactos que perduran

El atributo .name persiste a veces. Si configura df.columns = [''one'', ''two''] entonces df.one.name será ''one'' .

Si configura df.one.name = ''three'' , df.columns aún le dará [''one'', ''two''] , y df.one.name le dará ''three''

PERO

pd.DataFrame(df.one) devolverá

three 0 1 1 2 2 3

Porque los pandas reutilizan el .name de la serie ya definida.

Nombres de columnas multi nivel

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

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

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

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


Pandas 0.21+ Respuesta

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

  • El método de rename ha agregado el parámetro de axis que se puede establecer en columns o 1 . Esta actualización hace que este método coincida con el resto de la API de pandas. Todavía tiene los parámetros de index y columns , pero ya no está obligado a usarlos.
  • El método set_axis con el conjunto inplace en False permite cambiar el nombre de todas las etiquetas de índice o columna con una lista.

Ejemplos para Pandas 0.21+

Construir muestra DataFrame:

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 rename con axis=''columns'' o axis=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 utilizar la firma del método antiguo:

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

La función de rename 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_axis con una lista e inplace=False

Puede proporcionar una lista al método set_axis que es igual en longitud al número de columnas (o índice). Actualmente, los inplace predeterminados en el lugar son True , pero los valores predeterminados en el inplace serán False en futuras versiones.

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 de esta manera. Es una solución perfectamente buena.

La ventaja de usar set_axis es 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 a 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()


Soluciones de una línea o tubería.

Me centraré en dos cosas:

  1. OP establece claramente

    He guardado los nombres de columna editados 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 su lugar, quiero centrarme en reemplazar el objeto de columns existente por uno nuevo, dada una lista de nombres de columnas de reemplazo.

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

Configuración 1
Para centrarme en la necesidad de cambiar el nombre de reemplazar nombres de columna con una lista preexistente, crearé un nuevo df datos de muestra con nombres de columna iniciales y nombres de columna 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 antiguos nombres de columna a nuevos nombres de columna, podría usar 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 para rename . Lo siguiente se aprovecha del hecho de que al iterar sobre 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 sus columnas originales son únicos. Pero si no lo son, entonces esto se rompe.

Configuración 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

Solucion 2
pd.concat usando el argumento keys

Primero, note 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 asignamos la new lista como los nombres de columna. Terminamos repitiendo y765 . En su lugar, podemos usar el argumento de keys de la función pd.concat mientras pd.concat 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

Solucion 3
Reconstruir. Esto solo debe usarse si tiene un único tipo de dtype para todas las columnas. De lo contrario, terminará con el object dtype para todas las columnas y volver a convertirlas requiere más trabajo de diccionario.

dtype solo

pd.DataFrame(df.values, df.index, new) x098 y765 z432 0 1 3 5 1 2 4 6

dtype mixto

pd.DataFrame(df.values, df.index, new).astype(dict(zip(new, df.dtypes))) x098 y765 z432 0 1 3 5 1 2 4 6

Solucion 4
Este es un truco de trucos con transpose y set_index . pd.DataFrame.set_index nos permite establecer un índice en línea pero no hay un conjunto de set_columns correspondientes. Entonces podemos transponer, luego set_index , y transponer de vuelta. Sin embargo, aquí se aplica la misma advertencia de tipo de dtype frente a tipo mixto de la solución 3.

dtype solo

df.T.set_index(np.asarray(new)).T x098 y765 z432 0 1 3 5 1 2 4 6

dtype mixto

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

Solucion 5
Use una lambda en pd.DataFrame.rename que pd.DataFrame.rename cada elemento de new
En esta solución, pasamos un lambda que toma x pero luego lo ignora. También toma una y pero no lo espera. En su lugar, se asigna un iterador como valor predeterminado y luego puedo usarlo para recorrer uno por uno 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 lo indicó la gente en el chat de Sopython , si agrego un * entre y , puedo proteger mi variable y . Aunque, en este contexto, no creo que necesite protección. Todavía vale la pena mencionar.

df.rename(columns=lambda x, *, y=iter(new): next(y)) x098 y765 z432 0 1 3 5 1 2 4 6


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



Creo que este método es útil:

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

Este método le permite cambiar los nombres de columna individualmente.


El método de df.rename() 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)


En caso de que no quiera los nombres de fila df.columns = [''a'', ''b'',index=False]


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

Esto se podría haber hecho ejecutando un bucle for en df.columns y agregando las columnas eliminadas a df.columns.

En su lugar, podemos hacer esto de manera ordenada en una sola declaración usando la comprensión de lista como a continuación:

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

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


Otra opción es cambiar el nombre 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


Podrías usar str.slice para eso:

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


Prueba esto. Esto funciona para mi

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


Real solo uso simple

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

y asignará los nombres de las columnas por el orden en que los pones.


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

Mi método es genérico, en el que puede agregar delimitadores adicionales al separar los delimiters= con comas delimiters= variable y probarlo 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


Si tiene que lidiar con un montón de columnas nombradas por el sistema que está 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 creo un diccionario a partir de los nombres de las columnas del marco de datos usando expresiones regulares para eliminar ciertos apéndices de los nombres de las columnas y luego agrego reemplazos específicos al diccionario para nombrar las columnas centrales como se espera más adelante en la base de datos de recepción.

Esto se aplica a la trama de datos de una sola 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)


Si tienes el marco de datos, df.columns vuelca todo en una lista que puedes manipular y luego reasignar a tu 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? IDK. Una forma - si.

Una mejor manera de evaluar todas las técnicas principales presentadas en las respuestas a la pregunta es a continuación, utilizando cProfile para medir la memoria y el tiempo de ejecución. @kadee, @kaitlyn y @eumiro tuvieron 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" forma.

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


Solo .columns atributo .columns :

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


Tenga en cuenta que estos enfoques no funcionan para un MultiIndex. Para un MultiIndex, necesita 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


Use la función df.rename() y refiera las columnas a renombrar. No todas las columnas tienen que 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)


Ya que solo desea eliminar el signo $ en todos los nombres de columna, simplemente puede hacer:

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

O

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


Cambiar el nombre de las columnas del marco de datos y reemplazar el formato.

import pandas as pd data = {''year'':[2015,2011,2007,2003,1999,1996,1992,1987,1983,1979,1975], ''team'':[''Australia'',''India'',''Australia'',''Australia'',''Australia'',''Sri Lanka'',''Pakistan'',''Australia'',''India'',''West Indies'',''West Indies''], } df = pd.DataFrame(data) #Rename Columns df.rename(columns={''year'':''Years of Win'',''team'':''Winning Team''}, inplace=True) #Replace format df = df.columns.str.replace('' '', ''_'')


Renaming columns while reading the Dataframe: >>> df = pd.DataFrame({''$a'': [1], ''$b'': [1], ''$c'': [1]}).rename(columns = {''$a'' : ''a'',''$b'':''b'',''$c'':''c''}) Out[1]: a b c 0 1 1 1


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

Es una forma funcional de resolver esto.


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 tenía un diccionario codificado en antiguos nombres de columna a nuevos nombres de columna, 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 una asignación de diccionario, puede quitar el símbolo de $ inicial a través de una lista de comprensión:

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


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

Reemplazará los nombres existentes con los nombres que proporcione, en el orden que proporcione.



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 puedes editar manualmente los new_names como desees. Funciona muy bien cuando necesita cambiar el nombre de solo unas pocas columnas para corregir errores de ortografía, acentos, eliminar caracteres especiales, etc.