微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Pandas 类与 Pandas .p​​ipe()

如何解决Pandas 类与 Pandas .p​​ipe()

@pd.api.extensions.register_dataframe_accessor("data_cleaner")
class DataCleaner:

    def __init__(self,pandas_obj):
        self._obj = pandas_obj

    def multiply(self,col):
        self._obj[col] = self._obj[col] * self._obj[col]
        return self._obj 
    
    def square(self,col):
        self._obj[col] = self._obj[col]**2
        return self._obj 
    
    def add_strings(self,col):
        self._obj[col] = self._obj[col] + self._obj[col]
        return self._obj 

    def process_all(self):
        self._obj.pipe(
            self.multiply(col='A'),self.square(col='B')
            self.add_strings(col='C')
        )
    

class DataProcessor(DataCleaner):

    data = [
        [1,1.5,"AABB"],[2,2.5,"BBCC"],[3,3.5,"CCDD"],[4,4.5,"DDEE"],[5,5.5,"EEFF"],[6,6.5,"FFGG"],]

    def __init__(self):
        self.df = pd.DataFrame(data=DataProcessor.data,columns=['A','B','C'])

    def get_data(self):
        return self.df
    
    def clean_the_df(self,obj):
        obj = obj.data_cleaner.multiply(col='A')
        obj = obj.data_cleaner.square(col='B')
        obj = obj.data_cleaner.add_strings(col='C')
        return obj
    
    def process_all(self,obj):
        obj = obj.data_cleaner.process_all()


if __name__ == '__main__':
    

    data = DataProcessor().get_data()
    
    # this works
    print(DataProcessor().clean_the_df(data))
    
    # this does not work
    print(DataProcessor().process_all(data))

我想将 pandas .pipe() 函数与数据帧访问器一起使用,以将方法链接在一起。在 DataCleaner 类中,我有一个方法 process_all,其中包含类中的其他清理方法。我想将它们链接在一起并一次性使用多种方法处理数据帧。

将此链接方法保留在 DataCleaner 类中会很好,所以我所要做的就是从另一个类或文件调用它一次,例如process_all 内的 DataProcessor

这样我就不必单独写出每个方法来一次一个处理数据帧,例如在 DataProcessor.clean_the_df() 中。

问题在于 process_all 正在抱怨:TypeError: 'DataFrame' object is not callable

所以我的问题是,如何使用 pandas 数据帧访问器 self.obj.pipe()一个函数内的多个清理方法链接在一起,以便我可以从另一个类和进程调用函数一次包含多种方法的数据框?

process_all 的期望输出

    A      B         C
0   1   2.25  AABBAABB
1   4   6.25  BBCCBBCC
2   9  12.25  CCDDCCDD
3  16  20.25  DDEEDDEE
4  25  30.25  EEFFEEFF
5  36  42.25  FFGGFFGG

解决方法

这里的问题是 .pipe 需要一个接受 DataFrame、Series 或 GroupBy 对象的函数。文档对此非常清楚:https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.pipe.html。最重要的是,DataCleaner.process_all 函数没有正确实现 .pipe。为了链接几个函数,预期的语法是:

>>>(df.pipe(h)
...    .pipe(g,arg1=a)
...    .pipe(func,arg2=b,arg3=c)
... ) 

相当于

>>>func(g(h(df),arg1=a),arg3=c) 

为了将数据框访问器与 .pipe 结合使用,您需要在 DataCleaner 类中定义静态方法,这些方法将 DataFrame 和列作为参数。以下是解决您的问题的示例:

@pd.api.extensions.register_dataframe_accessor("data_cleaner")
class DataCleaner:
    def __init__(self,pandas_obj):
        self._obj = pandas_obj

    @staticmethod
    def multiply(df,col):
        df[col] = df[col] * df[col]
        return df 
    
    @staticmethod
    def square(df,col):
        df[col] = df[col]**2
        return df
    
    @staticmethod
    def add_strings(df,col):
        df[col] = df[col] + df[col]
        return df 

    def process_all(self):
        self._obj = (self._obj.pipe(self.multiply,col='A') 
                              .pipe(self.square,col='B')
                              .pipe(self.add_strings,col='C'))
        return self._obj 

class DataProcessor(DataCleaner):
    data = [
        [1,1.5,"AABB"],[2,2.5,"BBCC"],[3,3.5,"CCDD"],[4,4.5,"DDEE"],[5,5.5,"EEFF"],[6,6.5,"FFGG"],]
    def __init__(self):
        self.df = pd.DataFrame(data=DataProcessor.data,columns=['A','B','C'])

    def get_data(self):
        return self.df
    
    def clean_the_df(self,obj):
        obj = obj.data_cleaner.multiply(obj,col='A') # modified to use static method
        obj = obj.data_cleaner.square(obj,col='B')
        obj = obj.data_cleaner.add_strings(obj,col='C')
        return obj
    
    def process_all(self,obj):
        obj = obj.data_cleaner.process_all()
        return obj

使用此代码,运行它应该会产生:

>>>data = data = DataProcessor().get_data()
>>>print(DataProcessor().process_all(data))
    A      B         C
0   1   2.25  AABBAABB
1   4   6.25  BBCCBBCC
2   9  12.25  CCDDCCDD
3  16  20.25  DDEEDDEE
4  25  30.25  EEFFEEFF
5  36  42.25  FFGGFFGG

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。