我想了解code的这一行:
df.groupBy(someExpr).agg(somAgg).where(somePredicate)
我不知道如何使用Python链接该方法。我不想完全理解代码的前一行,只是想知道要研究的名称。我试图复制类似的东西,我很确定这不是一个很好的实现,但是我写了一个例子,说明我现在想如何获得想要的代码在后台运行:
class Example:
def __init__(self, *args):
self.list = [arg for arg in args]
def groupBy(self):
self.list = [value for value in self.list if isinstance(value, int)]
return self
def agg(self):
self.list = sum(self.list)
return self
def where(self, elem):
self.list = [value for value in self.list if value == elem]
return self
df = Example("a",1,3,3,5,"C","D")
df.groupBy().where(3).agg().list
我的问题是如何以最佳方式实现方法链?如果每种方法返回不同类型的值会怎样?如何在此处.list
的代码行中将此df.groupBy().where(3).agg().list
删除df.groupBy().where(3).agg()
?
答案 0 :(得分:1)
因此,这仅仅是一个软件包的砍刀设置。假设这是隐藏在df下的Pandas数据框。实际上,每个函数都会修改对象并返回其coppy(因此df被不必要地修改了)。因此,此调用可以翻译为:
df_grouped = df.groupBy(someExpr)
df_g_aggregated = df_grouped.agg(somAgg)
df_g_a_filtered = df_g_aggregated.where(somePredicate)
如果您要在定义下查看所有对象都返回相同的结果,则返回一个熊猫DataFrame,因此每个连续操作都依赖于相同的类。操作顺序将导致不同的结果,但在逻辑上是正确的,并且不会导致错误,因为group by的返回类型不是GroupedDataFrame,而是具有附加列group的DataFrame。
因此您的代码应如下所示:
class Example:
def __init__(self, *args):
self.list = [arg for arg in args]
def groupBy(self, key=None):
groups = #calculate groups for this dataset by key column
self.list = zip(self.list, groups)
return self
def agg(self, key=None):
sum = #calculate sum per each value of key column
self.list = zip(self.list, sum)
return self
def where(self, key, elem):
self.list = #filter column key by elem
return self
df = Example("a",1,3,3,5,"C","D")
df.groupBy().where(3).agg().list
自然地,我不会在这里实现所有这些功能,但是逻辑是总是返回类型应该相同,因此如果您执行sum([…]),它可能会返回单个整数。 在我的示例中,还有多余的就地修改,但是希望您能理解。
答案 1 :(得分:0)
这称为方法链接。注意,每个方法都返回self
,因此您提到的代码行可以按以下方式求值:
df.groupBy().where(3).agg().list
首先,df.groupBy()
返回df
,并对其进行了修改,因此它变为:
df.where(3).agg().list
类似地,df.where(3)
返回df
,并对其进行了修改,因此变为:
df.agg().list
最后,df.agg()
返回了df
,也对其进行了修改,因此变为:
df.list
最终结果等同于写作:
df = Example("a",1,3,3,5,"C","D")
df.groupBy()
df.where(3)
df.agg()
df.list