它如何在Python的下一行代码的幕后工作?

时间:2019-06-18 11:49:04

标签: python dataframe

我想了解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()

2 个答案:

答案 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