如何";附「;Python中对象的功能,例如数据帧?

如何";附「;Python中对象的功能,例如数据帧?,python,pandas,scala,Python,Pandas,Scala,也许这更像是一个理论性的语言问题,而不是熊猫本身。我有一组函数扩展,我想“附加”到例如pandas数据帧,而不显式调用实用程序函数并将数据帧作为参数传递,即具有语法糖。扩展Pandas数据帧也不是一种选择,因为定义和链接数据帧构造函数需要不可访问的类型,例如轴和数据类型 在Scala中,可以定义一个隐式类,将功能附加到其他不可用或太复杂而无法初始化的对象上,例如,字符串类型不能在Java AFAIR中扩展。例如,以下内容动态地将函数附加到字符串类型 同样,我希望能够做到: # somewhere

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

在Scala中,可以定义一个隐式类,将功能附加到其他不可用或太复杂而无法初始化的对象上,例如,字符串类型不能在Java AFAIR中扩展。例如,以下内容动态地将函数附加到字符串类型

同样,我希望能够做到:

# 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()
一种有效的可能性是使用Decorator模式,但我想知道Python是否提供了一种比Scala更少的锅炉板语言替代方案。

在pandas中,您可以:

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()
我想对于其他对象,您可以在类中定义一个方法来实现相同的结果

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)

对DataFrame进行子类化,除了添加功能外,不要做任何事情



相关-为什么不利用工厂模式在创建时将此功能添加到数据帧中,而不是在稍后执行时的某个未定义点?这将避免将数据框作为参数传递,并允许您标准化所添加的内容。pandas具有向导和可能的@Stephen副本不可能,您不能复制数据框构造函数,因为其依赖项类型无法访问。@天行者我相信您不需要复制数据框的构造函数。只需定义一个facory类,实例化它,然后将相同的参数传递给factory构造函数。然后,它的构造方法使用这些参数创建数据帧,添加附加函数,并返回新对象。谢谢!非常干净和简单,测试它。。。您的
A
定义本质上就是装饰器模式。
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)
import pd
import random,string

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

nrows = 10        
columns = ['b','d','a','c']
rows = [random.sample(string.ascii_lowercase,len(columns)) for _ in range(nrows)]
index = random.sample(string.ascii_lowercase,nrows)

df = Foo(rows,index,columns)
>>> df
   b  d  a  c
w  n  g  u  m
x  t  e  q  k
n  u  x  j  s
u  s  t  u  b
f  g  t  e  j
j  w  b  h  j
h  v  o  p  a
a  q  i  l  b
g  p  i  k  u
o  q  x  p  t
>>> df.lexi_sort()
>>> df
   a  b  c  d
a  l  q  b  i
f  e  g  j  t
g  k  p  u  i
h  p  v  a  o
j  h  w  j  b
n  j  u  s  x
o  p  q  t  x
u  u  s  b  t
w  u  n  m  g
x  q  t  k  e
>>