【问题标题】:How to extend the pandas' Dataframe class with my own methods and functions如何用我自己的方法和函数扩展 pandas 的 Dataframe 类
【发布时间】:2018-06-03 17:07:17
【问题描述】:

第一个问题:

我正在使用 pandas 的 DataFrames,并且我经常运行相同的例程作为数据预处理和其他事情的一部分。我想将其中一些例程编写为一个名为ExtendedDataframe 的类中的方法,该类扩展pandas.DataFrame。我不知道该怎么做。到目前为止,我没有在我的新类中写任何__init__,以便它继承自pandas.DataFrame

import pandas
class ExtendedDataframe(pandas.DataFrame):
  def some_method(self):
    blahblah

这显然使我能够通过继承创建ExtendedDataframe 的实例。但我通常通过pandas.read_csv 之类的方式加载数据,它返回经典的DataFrame。除了标准DataFrame 提供的方法之外,我如何才能加载此类 csv 数据并在某些时候将其转换为ExtendedDataframe 以使用我自己的方法?如果加载阶段返回一个标准的DataFrame,然后我将其转换为ExtendedDataframe,那很好。

第二个问题:

并非我使用的所有 pandas 功能都是 DataFrame 方法。有些是函数,例如 pandas.merge,它们将 DataFrames 作为参数。如何将此类函数的使用扩展到我的 ExtendedDataframe 类的实例?换句话说,如果df1df2ExtendedDataframe的两个实例,我该怎么做

pandas.merge([df1, df2], ...)

就像使用 DataFrame 的标准实例一样工作?

【问题讨论】:

    标签: python pandas class inheritance dataframe


    【解决方案1】:

    这并不能直接回答您的问题,但它是您问题的潜在答案。很多人在他们的工作流程中使用管道方法。

    https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.pipe.html

    而不是说

    df = foo(df)
    

    你可以说

    df = df.pipe(foo)
    

    您甚至可以为函数指定参数!这将比尝试封装整个数据框类更容易维护。所以这个想法是,您可以创建一个函数库并根据需要对它们进行管道传输。

    【讨论】:

    • 这确实是一个可能的解决方案,谢谢!是否有一种很好的通用方法可以简单地将方法/属性添加到内置类?
    • 您将遇到的问题是,一旦您调用内置方法,它将返回一个普通的 DataFrame,而不是您的自定义 DataFrame。
    • 好的,所以唯一的解决方案是修改内置类本身(我认为我不想这样做)?
    • 你绝对不想那样做。我的意思是说管道然后调用你想要的函数从长远来看会更可持续。这是我去年的解决方案,我没有发现任何问题。
    【解决方案2】:

    当您创建数据框的实例时,它们是 DataFrame 对象。您可以通过这种方式修改现有方法覆盖它们__existingMethod____ 关于第二个问题,我建议您创建一个新类,在其中传递 2 个数据框。在这种情况下,您将不得不创建____init____ 方法

    【讨论】:

      【解决方案3】:

      我不确定在哪个版本的 Pandas 中引入了用于扩展 DataFrame 等的装饰器。您可以在以下地址阅读更多相关信息:https://pandas.pydata.org/pandas-docs/stable/development/extending.html

      【讨论】:

        【解决方案4】:

        今天遇到同样的问题,在同事的帮助下,我发现这是可行的:

        import pandas as pd
        
        class MyDF(pd.DataFrame):
            def __init__(self, *args, **kwargs):
                super(MyDF,  self).__init__(*args, **kwargs)
        
            @property
            def _constructor(self):
                return MyDF
        
            def my_custom_method(self):
                print('This actually works!')
        

        例子:

        df = MyDF(columns=('a', 'b'))
        df = df.append({'a': 1, 'b': 'test'})
        print(df)
        df.my_custom_method()  # prints "This actually works!"
        

        【讨论】:

          【解决方案5】:

          你可以像这样扩展构造函数:

          import pandas
          from datetime import datetime
          
          class ExtendedDataframe(pandas.DataFrame):
            def __init__(self, *args, **kwargs):
              pandas.DataFrame.__init__(self, *args, **kwargs)
              self.created_at = datetime.today()
          
            def to_csv(self, *args, **kwargs):
              copy = self.copy()
              copy["created_at"] = self.created_at
              pd.DataFrame.to_csv(copy, *args, **kwargs)
          

          【讨论】:

            猜你喜欢
            • 2011-04-23
            • 2017-07-27
            • 1970-01-01
            • 2022-12-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-02-05
            • 2016-07-15
            相关资源
            最近更新 更多