¿Por qué la notación de puntos no funciona para eliminar una columna de un DataFrame de Pandas?

8 minutos de lectura

Avatar de usuario de John
John

Para eliminar una columna en un DataFrame, puedo usar con éxito:

del df['column_name']

Pero, ¿por qué no puedo usar lo siguiente?

del df.column_name

Dado que es posible acceder a la columna/Serie como df.column_nameesperaba que esto funcionara.

  • Tenga en cuenta que esta pregunta se está discutiendo en Meta.

    – RM

    22 mayo 2019 a las 16:37

Avatar de usuario de LondonRob
LondresRob

La mejor manera de hacer esto en Pandas es usar drop:

df = df.drop('column_name', axis=1)

donde 1 es el eje número (0 para filas y 1 para columnas).

Para eliminar la columna sin tener que reasignar df tu puedes hacer:

df.drop('column_name', axis=1, inplace=True)

Finalmente, para bajar por columna número en lugar de por columna etiquetaintente esto para eliminar, por ejemplo, las columnas 1, 2 y 4:

df = df.drop(df.columns[[0, 1, 3]], axis=1)  # df.columns is zero-based pd.Index

También trabajando con la sintaxis de “texto” para las columnas:

df.drop(['column_nameA', 'column_nameB'], axis=1, inplace=True)

Nota: Introducido en v0.21.0 (27 de octubre de 2017), el drop() El método acepta palabras clave de índice/columnas como alternativa a la especificación del eje.

Así que ahora podemos simplemente hacer:

df = df.drop(columns=['column_nameA', 'column_nameB'])

  • ¿Se recomienda esto sobre del ¿por alguna razón?

    – barbac

    10 de diciembre de 2013 a las 20:13

  • Aunque este método de eliminación tiene sus méritos, esta respuesta realmente no responde a la pregunta que se hace.

    – Pablo

    28 de mayo de 2014 a las 12:59

  • Cierto @Paul, pero debido al título de la pregunta, la mayoría de las personas que llegan aquí lo harán tratando de averiguar cómo eliminar una columna.

    – LondresRob

    28 mayo 2014 a las 16:43

  • @beardc otra ventaja de drop sobre del es eso drop le permite colocar varias columnas a la vez, realizar la operación en el lugar o no, y también eliminar registros a lo largo de cualquier eje (especialmente útil para una matriz 3-D o Panel)

    – placas

    14/04/2016 a las 20:17

  • Otra ventaja de drop sobre del es eso soltar es parte de la API de pandas y contiene documentación.

    – módulos

    12 de agosto de 2016 a las 8:53

Avatar de usuario de Wes McKinney
wes mckinney

Como habrás adivinado, la sintaxis correcta es

del df['column_name']

es dificil de hacer del df.column_name funcionan simplemente como resultado de las limitaciones sintácticas en Python. del df[name] se traduce a df.__delitem__(name) bajo las sábanas por Python.

  • Me doy cuenta de que esta es una “respuesta” súper antigua, pero mi curiosidad está picada: por qué ¿Es esa una limitación sintáctica de Python? class A(object): def __init__(self): self.var = 1 establece una clase, entonces a = A(); del a.var funciona bien…

    – dwanderson

    4 oct 2016 a las 14:24

  • @dwanderson, la diferencia es que cuando se debe eliminar una columna, el DataFrame debe tener su propio manejo para “cómo hacerlo”. En el caso de del df[name]se traduce a df.__delitem__(name) que es un método que DataFrame puede implementar y modificar según sus necesidades. En el caso de del df.name, la variable miembro se elimina sin posibilidad de que se ejecute ningún código personalizado. Considere su propio ejemplo: ¿puede obtener del a.var para dar como resultado una impresión de “eliminar variable”? Si puedes, por favor dime cómo. No puedo 🙂

    – Yonatan

    22 de diciembre de 2016 a las 8:27

  • @Yonatan Puedes usar cualquiera docs.python.org/3/reference/datamodel.html#object.__delattr__ o descriptores para eso: docs.python.org/3/howto/descriptor.html

    – Eugenio Pajomov

    19 de enero de 2017 a las 16:06

  • El comentario de @Yonatan Eugene también se aplica a Python 2; los descriptores han estado en Python 2 desde 2.2 y es trivial satisfacer su requisito;)

    – CS

    20 de junio de 2017 a las 12:38

  • Esta respuesta no es realmente correcta – la pandas desarrolladores nopero eso no significa que sea difícil de hacer.

    – wizzwizz4

    30 de septiembre de 2017 a las 9:42

Avatar de usuario de Krishna Sankar
krishna sankar

Utilizar:

columns = ['Col1', 'Col2', ...]
df.drop(columns, inplace=True, axis=1)

Esto eliminará una o más columnas en el lugar. Tenga en cuenta que inplace=True se agregó en pandas v0.13 y no funcionará en versiones anteriores. Tendrías que asignar el resultado de nuevo en ese caso:

df = df.drop(columns, axis=1)

avatar de usuario de jezrael
jezrael

Caer por índice

Suprímanse las columnas primera, segunda y cuarta:

df.drop(df.columns[[0,1,3]], axis=1, inplace=True)

Eliminar primera columna:

df.drop(df.columns[[0]], axis=1, inplace=True)

Hay un parámetro opcional. inplace para que los datos originales se puedan modificar sin crear una copia.

reventado

Selección de columna, adición, eliminación

Eliminar columna column-name:

df.pop('column-name')

Ejemplos:

df = DataFrame.from_items([('A', [1, 2, 3]), ('B', [4, 5, 6]), ('C', [7,8, 9])], orient="index", columns=['one', 'two', 'three'])

print df:

   one  two  three
A    1    2      3
B    4    5      6
C    7    8      9

df.drop(df.columns[[0]], axis=1, inplace=True)
print df:

   two  three
A    2      3
B    5      6
C    8      9

three = df.pop('three')
print df:

   two
A    2
B    5
C    8

avatar de usuario de firelynx
lince de fuego

La pregunta real planteada, perdida por la mayoría de las respuestas aquí es:

¿Por qué no puedo usar del df.column_name?

Primero necesitamos entender el problema, lo que requiere que nos sumerjamos en Métodos mágicos de Python.

Como Wes señala en su respuesta, del df['column'] asigna a Python metodo magico df.__delitem__('column') cual es implementado en Pandas para soltar la columna.

Sin embargo, como se señaló en el enlace anterior sobre Métodos mágicos de Python:

De hecho, __del__ casi nunca debe usarse debido a las precarias circunstancias en las que se llama; ¡utilízalo con precaución!

Podrías argumentar que del df['column_name'] no debe ser utilizado o fomentado, y por lo tanto del df.column_name ni siquiera debe ser considerado.

Sin embargo, en teoría, del df.column_name podría implementarse para trabajar en Pandas usando la metodo magico __delattr__. Sin embargo, esto introduce ciertos problemas, problemas que el del df['column_name'] la implementación ya lo ha hecho, pero en menor grado.

Problema de ejemplo

¿Qué sucede si defino una columna en un marco de datos llamado “dtypes” o “columns”?

Luego suponga que quiero eliminar estas columnas.

del df.dtypes haría el __delattr__ método confundido como si debería eliminar el atributo “dtypes” o la columna “dtypes”.

Cuestiones arquitectónicas detrás de este problema

  1. ¿Es un marco de datos una colección de columnas?
  2. ¿Es un marco de datos una colección de filas?
  3. ¿Es una columna un atributo de un marco de datos?

Pandas responde:

  1. si, en todos los sentidos
  2. No, pero si quieres que lo sea, puedes usar el .ix, .loc o .iloc métodos.
  3. Tal vez, ¿quieres leer ¿datos? Después si, a menos que el nombre del atributo ya está ocupado por otro atributo que pertenece al marco de datos. Quieres modificar ¿datos? Después no.

TLDR;

Tú no puedes hacer del df.column_nameporque Pandas tiene una arquitectura bastante desarrollada que debe reconsiderarse para que este tipo de disonancia cognitiva que no se les ocurra a sus usuarios.

Consejo profesional:

No utilice df.column_name. Puede ser bonito, pero causa disonancia cognitiva.

Citas de Zen of Python que encajan aquí:

Hay varias formas de eliminar una columna.

Debe haber una, y preferiblemente solo una, forma obvia de hacerlo.

Las columnas a veces son atributos pero a veces no.

Los casos especiales no son lo suficientemente especiales como para romper las reglas.

Lo hace del df.dtypes eliminar el atributo dtypes o la columna dtypes?

Frente a la ambigüedad, rechace la tentación de adivinar.

  • En realidad aborda la parte POR QUÉ de la pregunta original. Implementé subclases de pandas dataframe. Si lo hace, le enseñará parte vital de esta respuesta. La diferenciación de atributos y nombres de columnas es un gran problema. df.a deja ambigüedad si a es un atributo o un nombre de columna. Sin embargo, como se escribe pandas, df[“a”] solo puede ser una columna.

    – pauljohn32

    21 de julio de 2021 a las 4:43

  • ¡Esta es la única respuesta a la pregunta original que cubre todos los aspectos esenciales!

    – Joooeeey

    24 de enero a las 11:18

Avatar de usuario de Peter Mortensen
Pedro Mortensen

Una buena adición es la capacidad de soltar columnas solo si existen. De esta manera, puede cubrir más casos de uso, y solo eliminará las columnas existentes de las etiquetas que se le pasaron:

Simplemente agregue errores=”ignorar”por ejemplo.:

df.drop(['col_name_1', 'col_name_2', ..., 'col_name_N'], inplace=True, axis=1, errors="ignore")
  • Esto es nuevo desde pandas 0.16.1 en adelante. La documentación es aquí.

  • En realidad aborda la parte POR QUÉ de la pregunta original. Implementé subclases de pandas dataframe. Si lo hace, le enseñará parte vital de esta respuesta. La diferenciación de atributos y nombres de columnas es un gran problema. df.a deja ambigüedad si a es un atributo o un nombre de columna. Sin embargo, como se escribe pandas, df[“a”] solo puede ser una columna.

    – pauljohn32

    21 de julio de 2021 a las 4:43

  • ¡Esta es la única respuesta a la pregunta original que cubre todos los aspectos esenciales!

    – Joooeeey

    24 de enero a las 11:18

Avatar de usuario de Peter Mortensen
Pedro Mortensen

Desde la versión 0.16.1, puedes hacer

df.drop(['column_name'], axis = 1, inplace = True, errors="ignore")

  • Y esto también admite la eliminación de varias columnas, algunas de las cuales no tienen por qué existir (es decir, sin generar un error errors= 'ignore') df.drop(['column_1','column_2'], axis=1 , inplace=True,errors= 'ignore')si tal aplicación lo desea!

    – muón

    21/10/2016 a las 19:57


¿Ha sido útil esta solución?