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