首页 > 解决方案 > 当我保存为 tools.py 文件时,我的函数定义给出了不同的结果

问题描述

我在 Jupiter 实验室写了两个函数。当我将它们集成到tools.py文件中并导入 Jupyter 实验室时,我得到了不同的结果。谁能告诉我有什么区别?

实际上,这些函数用于将一种嵌套数据框转换为平面数据框。我觉得问题出在我曾经用两个参数应用函数的方式上

这是我在 jupyter 实验室的代码:

def findTS(s):
    out=""
    for i,r in om.iterrows():
        sci=r["sec_ID"]
        if sci in s:
            out=r["type_sec"]

            exit
    return(out)
def Js2Geodf(df): 
# df=OmegaJ["chapters"][0]
    om=json_normalize(df,"section")
    om=om.dropna(subset=["sec_part"])
    l=[]
    for i,x in om.iterrows():
        k={"type_sec":x["type_sec"]}
        l.append([x["sec_part"]])
        listItems=list(flatten_list(l))
        dfout=pd.DataFrame(listItems)
        dfout["type_sec"]=dfout.apply(lambda x: findTS(x["ID"]),axis=1)
        return(dfout)

然后我以一种我可以独立使用它们作为模块中的方法的方式集成它们tools.py

def findTS(s,df):
    out=""
    om=json_normalize(df,"section")
    for i,r in om.iterrows():
        sci=r["sec_ID"]
        if sci in s:
            out=r["type_sec"]

            exit
    return(out)
def Js2Geodf(df): 
# df=OmegaJ["chapters"][0]
    om=json_normalize(df,"section")
    om=om.dropna(subset=["sec_part"])
    l=[]
    for i,x in om.iterrows():
        k={"type_sec":x["type_sec"]}
        l.append([x["sec_part"]])
    listItems=list(flatten_list(l))
    dfout=pd.DataFrame(listItems)
    dfout["type_sec"]=dfout.apply(lambda x: findTS(x["ID"],df),axis=1)
    return(dfout)

正如您在每个函数中看到的,有一些小的变化。

在第一个函数中:

-def findTS(s)--->def findTS(s,df)
-adding ....om=json_normalize(df,"section")

在最后一行的第二个函数中:

-dfout["type_sec"]=dfout.apply(lambda x: findTS(x["ID"]),axis=1)-->
-dfout["type_sec"]=dfout.apply(lambda x: findTS(x["ID"],df),axis=1)

问题是它给了我不同的结果,我有点怀疑 apply 和 lambda 的使用有两个参数。

标签: pythonfunctionapply

解决方案


没有实际数据很难弄清楚,但这里一件可能是负责任的:

  1. 原始变体:

    • Js2Geodf

      # ...
      om = json_normalize(df, "section")  # @TODO - cfati: MARKED LINE 1
      om = om.dropna(subset=["sec_part"])  # @TODO - cfati: MARKED LINE 2
      # ...
      
    • 查找TS

      # ...
      for i, r in om.iterrows():
      # ...
      

    findTS中,您对执行MARKED LINE 2后产生的om变量(来自Js2Geodf )进行操作

  2. 修改变体:

    • Js2Geodf

      事情与#1中的完全一样。

    • 查找TS

      # ...
      om = json_normalize(df, "section")  # @TODO - cfati: Identical to MARKED LINE 1
      for i, r in om.iterrows():
      # ...
      

    findTS中,您对此处定义的om变量进行操作,其定义与MARKED LINE 1相同,因此:

    • 错过了 MARKED LINE 2
    • 每次调用findTS时执行此行也非常低效

正如我在评论中所说(当时我只看到了一个设计缺陷,现在很明显这也是代码中的一个语义缺陷),将om作为参数而不是df传递。
下面是代码(我也做了一些小的改进,还有很大的改进空间,但我没有按照逻辑,所以我没有改变它):

def findTS(s, om):
    for i, r in om.iterrows():
        sci = r["sec_ID"]
        if sci in s:
            return r["type_sec"]
    return ""


def Js2Geodf(df): 
    #df = OmegaJ["chapters"][0]
    om = json_normalize(df, "section")
    om = om.dropna(subset=["sec_part"])
    l = []
    for i, x in om.iterrows():
        l.append([x["sec_part"]])
    listItems = list(flatten_list(l))
    dfout = pd.DataFrame(listItems)
    dfout["type_sec"] = dfout.apply(lambda x: findTS(x["ID"], om), axis=1)
    return dfout

@EDIT0

也从评论中总结信息:

  • Js2Geodf的最后 4 行缩进在原始变体和修改变体中有所不同(我认为这是前者的错字)
  • 确保输入数据在运行(以及不同的代码版本)中保持不变。显然,这引起了很多麻烦,一旦解决,代码也能正常工作

推荐阅读