如何将功能“附加”到 Python 中的对象,例如 Pandas DataFrame?

Sky*_*ker 4 python scala pandas

也许这更像是一个理论语言问题,而不是熊猫本身。我有一组函数扩展,我想“附加”到例如 Pandas DataFrame 而不显式调用实用程序函数并将 DataFrame 作为参数传递,即具有语法糖。扩展 Pandas DataFrame 也不是一种选择,因为需要定义和链接 DataFrame 构造函数的不可访问类型,例如AxesDtype

在 Scala 中,可以定义一个隐式类来将功能附加到一个否则不可用或过于复杂而无法初始化的对象上,例如 String 类型不能在 Java AFAIR 中扩展。例如,以下将函数动态附加到 String 类型https://www.oreilly.com/library/view/scala-cookbook/9781449340292/ch01s11.html

scala> implicit class StringImprovements(s: String) {
    def increment = s.map(c => (c + 1).toChar)
}

scala> val result = "HAL".increment   
result: String = IBM
Run Code Online (Sandbox Code Playgroud)

同样,我希望能够做到:

# somewhere in scope
def lexi_sort(df):
    """Lexicographically sorts the input pandas DataFrame by index and columns""" 
    df.sort_index(axis=0, level=df.index.names, inplace=True)
    df.sort_index(axis=1, level=df.columns.names, inplace=True)
    return df

df = pd.DataFrame(...)
# some magic and then ...
df.lexi_sort()
Run Code Online (Sandbox Code Playgroud)

一种有效的可能性是使用装饰器模式,但我想知道 Python 是否提供了一种像 Scala 那样的样板语言替代品。

use*_*262 5

在熊猫中,您可以执行以下操作:

def lexi_sort(df):
    """Lexicographically sorts the input pandas DataFrame by index and columns"""
    df.sort_index(axis=0, level=df.index.names, inplace=True)
    df.sort_index(axis=1, level=df.columns.names, inplace=True)
    return df

pd.DataFrame.lexi_sort = lexi_sort

df = pd.read_csv('dummy.csv')
df.lexi_sort()
Run Code Online (Sandbox Code Playgroud)

我想对于其他对象,您可以在类中定义一个方法来实现相同的结果。

class A():
    def __init__(self, df:pd.DataFrame):
        self.df = df
        self.n = 0

    def lexi_sort(self):
        """Lexicographically sorts the input pandas DataFrame by index and columns"""
        self.df.sort_index(axis=0, level=self.df.index.names, inplace=True)
        self.df.sort_index(axis=1, level=self.df.columns.names, inplace=True)
        return df

    def add_one(self):
        self.n += 1

a = A(df)
print(a.n)
a.add_one()
print(a.n)
Run Code Online (Sandbox Code Playgroud)