Как удалить столбец в 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 с помощью:
del df['column_name']
Однако это не работает:
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 (быстрые примеры)
- Почему del df.column_name не работает (точечная нотация)
- Внутреннее устройство: delitem vs delattr
- Практические методы: del, pop, drop — плюсы и примеры
- Когда точечная нотация подходит и её ограничения
- FAQ: можно ли переопределить поведение?
- Источники
- Заключение
Как удалить столбец в Pandas (pandas удалить столбец)
Коротко — безопасные и рекомендуемые способы удалить столбец из DataFrame:
- Быстро убрать столбец (in-place):
del df['column_name']
- Удалить и получить удалённый Series:
s = df.pop('column_name') # возвращает Series и удаляет столбец из df
- Удалить один или несколько столбцов, вернуть новый DataFrame:
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)
Когда и что лучше использовать.
- del df[‘col’]
- Прямо, быстро, изменяет DataFrame на месте.
- Удобно в интерактивной работе и скриптах.
- Пример:
del df['age']
- df.pop(‘col’)
- Удаляет и возвращает Series — полезно, если нужен удалённый столбец.
age_series = df.pop('age')
- df.drop(columns=…) / df.drop([…], axis=1)
- Более выразительно для нескольких колонок; можно выбирать inplace или получить новый DataFrame.
df = df.drop(columns=['a','b']) # возвращает копию без колонок
# или
df.drop(columns=['a','b'], inplace=True)
.drop хорош для чистоты кода и когда удаление — часть цепочки преобразований.
Рекомендация: для программного удаления по переменной используйте скобочную нотацию:
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__, который будет переводить удаление атрибута в удаление столбца:
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).
Источники
- Delete a column from a Pandas DataFrame - Stack Overflow
- How to delete a column in pandas — Educative
- Удаление столбца из DataFrame в Pandas — CoreDumped (RU)
- Почему del df.loc[:, column] не работает — Stack Overflow
- 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 — так код будет предсказуемым, устойчивым к конфликтам имён и корректно работать с любыми названиями столбцов.