본문 바로가기

개발하자

Python: 상속된 부모 클래스 메서드 호출 실패

반응형

Python: 상속된 부모 클래스 메서드 호출 실패

기존 클래스를 중심으로 패스스루 래퍼 클래스를 만들었지만 예상대로 작동하지 않습니다.

import pandas as pd
from sklearn.preprocessing import OrdinalEncoder

tiny_df = pd.DataFrame({'x': ['a', 'b']})

class Foo(OrdinalEncoder):

    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)

    def fit(self, X, y=None):
        super().fit(X, y)
        return self


oe = OrdinalEncoder()
oe.fit(tiny_df) # works fine
foo = Foo()
foo.fit(tiny_df) # fails

수신되는 오류 메시지의 관련 부분은 다음과 같습니다.

~\.conda\envs\pytorch\lib\site-packages\sklearn\preprocessing\_encoders.py in _fit(self, X, handle_unknown)
     69                         raise ValueError("Unsorted categories are not "
     70                                          "supported for numerical categories")
---> 71             if len(self._categories) != n_features:
     72                 raise ValueError("Shape mismatch: if n_values is an array,"
     73                                  " it has to be of shape (n_features,).")

TypeError: object of type 'Foo' has no len()

내가 수업 방법으로 부모 생성자를 불렀음에도 불구하고 어쩐지 부모의 사유 재산이 정해지지 않는 것 같다. 제가 여기서 뭔가 간단한 것을 놓치고 있는 게 분명한데, 어떤 도움이든 감사하겠습니다!




함수로 다시 전달할 필요가 없습니다. 그리고 의 추정기는 항상 그들의 서명에 그들의 매개변수를 지정해야 하며, 그렇지 않으면 당신은 a를 얻을 것이므로, 당신은 그것을 제거해야 한다. 당신의 코드를 아래와 같이 수정했습니다.

import pandas as pd
from sklearn.preprocessing import OrdinalEncoder

tiny_df = pd.DataFrame({'x': ['a', 'b']})

class Foo(OrdinalEncoder):

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

    def fit(self, X, y=None):
        super().fit(X, y)
        return self


oe = OrdinalEncoder()
oe.fit(tiny_df) # works fine
foo = Foo()
foo.fit(tiny_df) # works fine too

샘플 출력

foo.transform(tiny_df)
array([[0.],
       [1.]])

약간의 추가

class Foo(OrdinalEncoder):

    def __init__(self, *args, **kwargs):
        super().__init__(*args,**kwargs)

    def fit(self, X, y=None):
        super().fit(X, y)
        return self

생성할 때:

foo= Foo()

RuntimeError: scikit-learn estimators should always specify their parameters in the signature of their __init__ (no varargs). <class '__main__.Foo'> with constructor (self, *args, **kwargs) doesn't  follow this convention.

반응형