Я создаю подкласс 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. Спасибо.
Да, но тогда возникает 2 проблемы: (1) myattr не будет прикреплен к копиям моего объекта и (2) выдает предупреждение: UserWarning: Pandas не позволяет создавать столбцы с помощью нового имени атрибута
Ну, я не знаю, насколько это будет проблематично для вас, но рассмотрите возможность создания класса, который не будет наследоваться от DataFrame, а вместо этого будет содержать его, как, например, self.df = pd.DataFrame. Композиция в этом случае выглядит как лучшее решение, потому что вам не нужно будет приспосабливаться к реализации DataFrame за счет ее упаковки. Конечно, это не лучшее решение во всех случаях, но все же подумайте :)
Спасибо за совет. Наконец мне удалось найти решение, определив атрибут в __init__ и переопределив метод copy, который теперь также копирует мой атрибут в новый DataFrame. Затем я использую copy() для дублирования своего объекта.






Назначение атрибутов экземпляра подклассу 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. Временные свойства не сохраняются после модификации фрейма данных.
Вы можете просто определить атрибут в
__init__self.myattr = [], тем самым вы уверены, что это атрибут экземпляра;)