Как определить атрибут экземпляра в подклассе pandas DataFrame?

Я создаю подкласс pandas DataFrame и хочу иметь атрибут.

class MyFrame(pd.DataFrame):


    _metadata = ['myattr']
    myattr = []


    def __init__(self, *args, **kwargs):
        pd.DataFrame.__init__(self, *args, **kwargs)

        self.myattr.append(0)


    @property
    def _constructor(self):
        return AutoData

Моя проблема в том, что myattr является атрибутом класса. Когда я изменяю его в экземпляре моего класса, все экземпляры изменяются:

mf2 = mf
mf2.myattr.append(1)
print(mf.myattr)
>>> [0, 1]

Но я хочу, чтобы атрибут был прикреплен к его экземпляру. Другими словами, модифицируйте myattr только для mf2, но не для mf. Спасибо.

Вы можете просто определить атрибут в __init__self.myattr = [], тем самым вы уверены, что это атрибут экземпляра;)

Damian 27.01.2019 03:07

Да, но тогда возникает 2 проблемы: (1) myattr не будет прикреплен к копиям моего объекта и (2) выдает предупреждение: UserWarning: Pandas не позволяет создавать столбцы с помощью нового имени атрибута

Adrien Pavao 27.01.2019 03:15

Ну, я не знаю, насколько это будет проблематично для вас, но рассмотрите возможность создания класса, который не будет наследоваться от DataFrame, а вместо этого будет содержать его, как, например, self.df = pd.DataFrame. Композиция в этом случае выглядит как лучшее решение, потому что вам не нужно будет приспосабливаться к реализации DataFrame за счет ее упаковки. Конечно, это не лучшее решение во всех случаях, но все же подумайте :)

Damian 27.01.2019 03:22

Спасибо за совет. Наконец мне удалось найти решение, определив атрибут в __init__ и переопределив метод copy, который теперь также копирует мой атрибут в новый DataFrame. Затем я использую copy() для дублирования своего объекта.

Adrien Pavao 28.01.2019 02:18
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
4
411
1

Ответы 1

Назначение атрибутов экземпляра подклассу pd.DataFrame может быть выполнено следующим образом:

class MyFrame(pd.DataFrame):
    _metadata = ['myattr']

    def __init__(self, *args, **kwargs):
        pd.DataFrame.__init__(self, *args, **kwargs)
        self.myattr = [0]

    @property
    def _constructor(self):
        return MyFrame

Список _metadata устанавливает атрибуты, которые не следует рассматривать как столбцы. Имена, перечисленные в _metadata, учитываются в методах __setattr__() и __getattr__() родительского класса pd.DataFrame (которым является NDFrame) и устанавливаются как атрибуты объекта без повышения Предупреждение пользователя.

Хотя _metadata являются обычными свойствами, существует также возможность установить временные свойства с помощью _internal_names, как описано в документация pandas. Временные свойства не сохраняются после модификации фрейма данных.

Другие вопросы по теме