Создание подкласса класса pd.DataFrame приводит к тому, что `object не имеет атрибута _data 'при попытке отобразить данные - PullRequest
0 голосов
/ 09 февраля 2020

Я пытаюсь создать (очень простой) pandas подкласс, likeso:

import pandas as pd

data = pd.DataFrame({'A': [1, 2], 'B': [2, 3], 'C': [4, 5]})

class TestFrame(pd.DataFrame):
    # See https://pandas.pydata.org/pandas-docs/stable/development/extending.html#extending-extension-types
    _metadata = pd.DataFrame._metadata + ["addnl"]

    @property
    def _constructor(self):
        return TestFrame

    @property
    def _constructor_sliced(self):
        return pd.Series

    @classmethod
    def plus_one(
        cls,
        df,
    ):
        tf = super().__new__(cls, df)
        tf.addnl = 1
        return tf

t1 = TestFrame.plus_one(data)

Это происходит без ошибок, за исключением того, что попытка просмотра t1 дает мне AttributeError: 'TestFrame' object has no attribute '_data'.

Я думаю, это потому, что я звоню DataFrame.__new__ вместо __init__, потому что это выдает ту же ошибку:

object.__new__(pd.DataFrame, {'A': [1, 2], 'B': [2, 3], 'C': [4, 5]})

Однако я не могу найти способ определить конструктор c становится еще более проблематичным из-за того, что инфраструктура подклассов pandas еще (насколько я могу судить) не позволяет определять __init__ с новыми атрибутами.

Любая помощь очень оценили.

1 Ответ

2 голосов
/ 09 февраля 2020

Проблема здесь в том, что строка tf = super().__new__(cls, df) не имеет смысла. Вы не переопределяете DataFrame.__init__ или __new__, поэтому вам не нужно использовать super() для их вызова.

Если идея заключается в создании фрейма типа TestFrame, вы можете использовать tf = cls(df).

@classmethod
def plus_one(cls, df):
    tf = cls(df)
    tf.addnl = 1

    return tf
...