Программирование

Как удалить столбец в Pandas: del df['col'] vs df.col

Узнайте, как удалить столбец из DataFrame Pandas с помощью del df['column'], pop() или drop(). Почему точечная нотация del df.column_name не работает? Объяснение __delitem__ vs __delattr__ с примерами и лучшими практиками pandas удалить столбец.

Как удалить столбец из DataFrame Pandas и почему точечная нотация не работает с оператором del

Я могу успешно удалить столбец в DataFrame с помощью:

python
del df['column_name']

Однако это не работает:

python
del df.column_name

Поскольку возможно получить доступ к столбцу как к Series с помощью df.column_name, почему я не могу использовать точечную нотацию с оператором del для удаления столбца?

В Pandas удалить столбец проще и корректнее через индексатор или методы: del df['column_name'], df.pop('column_name') или df.drop(columns=['column_name']) — это стандартные способы для pandas удалить столбец. Оператор del для del df['col'] вызывает __delitem__, который DataFrame реализует; а del df.column_name пытается вызвать __delattr__, который для динамических колонок в Pandas не переопределён, поэтому так не работает. Используйте скобочную нотацию или .pop/.drop — они однозначны и безопасны для pandas dataframe.


Содержание


Как удалить столбец в Pandas (pandas удалить столбец)

Коротко — безопасные и рекомендуемые способы удалить столбец из DataFrame:

  • Быстро убрать столбец (in-place):
python
del df['column_name']
  • Удалить и получить удалённый Series:
python
s = df.pop('column_name') # возвращает Series и удаляет столбец из df
  • Удалить один или несколько столбцов, вернуть новый DataFrame:
python
df2 = df.drop(columns=['col1', 'col2'])
# или изменить на месте:
df.drop(columns=['col1'], inplace=True)

.drop удобен, когда нужно удалить сразу несколько колонок или управлять осью. Подробнее о вариантах удаления и примерах см. руководство по удалению столбцов: https://www.educative.io/answers/how-to-delete-a-column-in-pandas.


Почему del df.column_name не работает (точечная нотация)

Почему же df.column_name часто возвращает Series, а del df.column_name — нет? Всё упирается в семантику Python: точечная нотация — это доступ к атрибуту объекта, а не к элементу контейнера. Когда вы пишете df.column_name, Pandas реализует механизм (фолбэк через __getattr__), который позволяет искать колонку по имени и вернуть Series. Но del df.column_name вызывает совсем другой путь — __delattr__ на объекте, и Pandas не использует этот путь для удаления колонок. Подробнее о том, как работает оператор del в Python, читайте в обзоре механики del: https://realpython.com/python-del-statement/.

Коротко: доступ через точку — это удобство для чтения/быстрого доступа, но не полноценная операция с элементами DataFrame. Для изменения структуры (удаление колонок) нужно использовать методы/индексатор.


Внутреннее устройство: delitem vs delattr

Немного технически, но просто:

  • del obj.attr → вызывает obj.delattr(‘attr’)
  • del obj[‘key’] → вызывает obj.delitem(‘key’)

Pandas реализует DataFrame.__delitem__ — это та функция, которая обрабатывает удаление столбца по метке. Поэтому del df['col'] работает и корректно удаляет колонку из внутренней структуры DataFrame. Но Pandas не реализует удаление колонок через __delattr__ (удаление атрибутов). Объяснение и обсуждение этой разницы хорошо показано в обсуждении на Stack Overflow: https://stackoverflow.com/questions/13411544/delete-a-column-from-a-pandas-dataframe.

Ещё нюанс: df.column_name доступен только если имя колонки — допустимый Python-идентификатор и не конфликтует с реальными атрибутами/методами DataFrame (например, shape, columns, index, drop и т.д.). Поэтому поведение точечной нотации непредсказуемо в некоторых случаях — и её не сделали полноценным API для операций изменения структуры, чтобы избежать неожиданных побочных эффектов.

Также стоит заметить: выражение вроде del df.loc[:, 'col'] не работает, потому что df.loc возвращает indexer-объект (LocIndexer), а не сам DataFrame — удаление через такой путь не предусмотрено (подробнее в обсуждении: https://stackoverflow.com/questions/62761682/python-pandas-why-doesnt-del-df-loc-column-name-work-even-though-del-df).


Практические методы: del, pop, drop — плюсы и примеры (pandas drop)

Когда и что лучше использовать.

  1. del df[‘col’]
  • Прямо, быстро, изменяет DataFrame на месте.
  • Удобно в интерактивной работе и скриптах.
  • Пример:
python
del df['age']
  1. df.pop(‘col’)
  • Удаляет и возвращает Series — полезно, если нужен удалённый столбец.
python
age_series = df.pop('age')
  1. df.drop(columns=…) / df.drop([…], axis=1)
  • Более выразительно для нескольких колонок; можно выбирать inplace или получить новый DataFrame.
python
df = df.drop(columns=['a','b']) # возвращает копию без колонок
# или
df.drop(columns=['a','b'], inplace=True)

.drop хорош для чистоты кода и когда удаление — часть цепочки преобразований.

Рекомендация: для программного удаления по переменной используйте скобочную нотацию:

python
col = 'my column'
del df[col] # безопасно
df.pop(col) # если нужен результат
df.drop(columns=[col])

Избегайте del df.column_name в коде, который должен работать над любыми именами столбцов или в продакшен-сценариях — это хрупко.


Когда точечная нотация подходит и её ограничения

Точечная нотация полезна для быстрого чтения/дебага:

  • когда имя столбца — простой идентификатор (без пробелов, дефисов, начинающийся не с цифры),
  • и когда имя не совпадает с существующим атрибутом DataFrame.

Но ограничения существенны:

  • Колонка с именем shape или columns никогда не будет доступна через df.shape как Series — это свойство DataFrame.
  • Если имя содержит пробелы или дефисы — df.my-col не сработает.
  • Точечная нотация не даёт однозначности для операций удаления и присваивания; лучше всегда использовать df['...'] для модификаций.

Коротко: точечная нотация — удобный синтаксический сахар для чтения, но не для управления столбцами.


FAQ: можно ли переопределить поведение?

Вопрос: а можно как-то заставить del df.column работать (переопределить delattr)?
Ответ: технически да — можно создать подкласс DataFrame и реализовать __delattr__, который будет переводить удаление атрибута в удаление столбца:

python
import pandas as pd

class MyDF(pd.DataFrame):
 def __delattr__(self, name):
 if name in self.columns:
 self.__delitem__(name)
 else:
 super().__delattr__(name)

Но это хак: ломает ожидания, совместимость с библиотеками и может создать трудночитаемый код. Гораздо практичнее и безопаснее придерживаться стандартных методов (del df['col'], .pop, .drop).


Источники

  1. Delete a column from a Pandas DataFrame - Stack Overflow
  2. How to delete a column in pandas — Educative
  3. Удаление столбца из DataFrame в Pandas — CoreDumped (RU)
  4. Почему del df.loc[:, column] не работает — Stack Overflow
  5. Python’s del: Remove References From Scopes and Containers — Real Python

Заключение

Если нужно pandas удалить столбец — используйте del df['col'], df.pop('col') или df.drop(columns=[...]). Точечная нотация (df.col) — лишь удобный доступ для чтения и реализована через __getattr__, но удаление через del df.col не работает, потому что del вызывает __delattr__, а Pandas не использует его для удаления колонок. В практическом коде всегда предпочитайте скобочную нотацию или методы .pop/.drop — так код будет предсказуемым, устойчивым к конфликтам имён и корректно работать с любыми названиями столбцов.

Авторы
Проверено модерацией
Модерация