从iterrows()转到更快的“嵌套-Pythonish-循环”

时间:2019-09-04 08:16:30

标签: python pandas vectorization

我试图将一段代码从iterrows()演化为更快的东西,因为我有一个嵌套循环,所以复杂度太大。

我发现apply和vectorization更好,但是不了解如何使它适用于嵌套循环。

这就是我现在正在做的。

clean = df.drop_duplicates(subset = "DESCRIPTION", keep = "first")
clean = clean.drop_duplicates(subset = "IMAGES", keep = "first")

##methode naive et un poil onereuse (n^2) pour ajouter les donnees extraites     
for index, crow in tqdm(clean.iterrows()):
for drow in df.iterrows():
    if crow["DESCRIPTION"] == drow[1]["DESCRIPTION"] or (crow["IMAGES"] == drow[1]["IMAGES"] and crow["IMAGES"] != []):
        if crow["CRAWL_SOURCE"] != drow[1]["CRAWL_SOURCE"] and crow["CRAWL_SOURCE"] not in drow[1]["CRAWL_SOURCE"]:
            clean.loc[index, "CRAWL_SOURCE"] = crow["CRAWL_SOURCE"] + " " + drow[1]["CRAWL_SOURCE"]

我要删除重复项并将干净的数据集保存在“ clean”变量中。 由于我仍然需要保留重复数据,因此我运行了一个嵌套循环,以从未更改的原始df中获取所需信息。

我是Python的新手,所以我可能做错了,但是我想对这个嵌套循环进行矢量化处理。

Dataset example 绿色是DESCRIPTION字段,它是创建重复项的地方。 数据集“ clean”没有重复项,它来自数据集“ df”。 数据集“ df”包含双打以及它们具有的附加数据。

我最后想要的是“干净”数据集包含可以在“ df”的“ CRAWL_SOURCE”列中找到的附加信息。 像这样: result

第一行没有重复,因此只有一个黄色值。 第二行重复,因此我添加了信息。

2 个答案:

答案 0 :(得分:1)

如果数据框“干净”源自数据框“ df”,则只需删除重复项并获取所有信息。

df_clean = df.drop_duplicates(subset = ["columnX", "columnY"], keep = "first").drop_duplicates(subset = "DESCRIPTION", keep = "first")

如果不是这种情况,您可以简单地加入或合并要添加回去的信息,如下所示:

df_result = df_clean.reset_index().merge(df, on=["DESCRIPTION","CRAWL_SOURCE"], how="left").set_index("index")

请注意,“ on = []”参数需要您要匹配的列表。

答案 1 :(得分:1)

根据我对您代码的了解,您希望每个IMAGE都有一行,并且所有CRAWL_SOURCEIMAGEDESCRIPTION会出现在此IMAGE的一个实例中,即使它是另一个IMAGE。如果我弄错了,请发表评论,然后将其删除,但这就是我想出的(我知道那是一团糟,也许有人会找到一种“更清洁”的方式):

import itertools
df1 = df.groupby(['IMAGES']).agg(lambda x: list(x))['CRAWL_SOURCE'].reset_index()
df2 = df.groupby(['DESCRIPTION']).agg(lambda x: list(x))  
['CRAWL_SOURCE'].reset_index()
clean = df.merge(df1.rename({'CRAWL_SOURCE': 'CSI'}, axis=1), how='left').merge(df2.rename({'CRAWL_SOURCE': 'CSD'}, axis=1), how='left')
clean['CRAWL_SOURCE'] = clean['CSI'] + clean['CSD']
clean = clean.groupby(['IMAGES'])\
.agg(lambda x: ' '.join(list(set(list(itertools.chain.from_iterable(x)))))) 
['CRAWL_SOURCE'].reset_index()