【问题标题】:How to optimize this python code? I need to improve its runtime如何优化这个python代码?我需要改进它的运行时间
【发布时间】:2018-07-26 14:48:46
【问题描述】:

我想优化这个过滤功能。它在两个列表中搜索:一个是类别,一个是标签。这就是为什么运行此功能需要很长时间的原因。

def get_percentage(l1, l2, sim_score):
    diff = intersection(l1, l2)
    size = len(l1)
    if size != 0:
        perc = (diff/size)
        if perc >= sim_score:
                return True
    else:
        return False

def intersection(lst1, lst2):
    return len(list(set(lst1) & set(lst2)))

def filter_entities(country, city, category, entities, entityId):
    valid_entities = []
    tags = get_tags(entities, entityId)
    for index, i in entities.iterrows():
        if i["country"] == country and i["city"] == city:
            for j in i.categories:
                if j == category:
                    if(get_percentage(i["tags"], tags, 0.80)):
                        valid_entities.append(i.entity_id)

    return valid_entities

【问题讨论】:

标签: python performance optimization execution-time


【解决方案1】:

你有几个不必要的for 循环和if 在那里你可以删除,你绝对应该利用df.loc 从你的数据框中选择元素(假设entities 一个 Pandas 数据框):

def get_percentage(l1, l2, sim_score):
    if len(l1) == 0:
        return False  # shortcut this default case
    else:
        diff = intersection(l1, l2)
        perc = (diff / len(l1))
        return perc >= sim_score  # rather than handling each case separately

def intersection(lst1, lst2):
    return len(set(lst1).intersection(lst2))  # almost twice as fast this way on my machine

def filter_entities(country, city, category, entities, entityId):
    valid_entities = []
    tags = get_tags(entities, entityId)
    # Just grab the desired elements directly, no loops
    entity = entities.loc[(entities.country == county) &
                          (entities.city == city)]
    if category in entity.categories and get_percentage(entity.tags, tags, 0.8):
        valid_entities.append(entity.entity_id)
    return valid_entities

很难肯定这会有所帮助,因为我们无法真正运行您提供的代码,但这应该可以消除一些低效问题并利用 Pandas 中的一些优化。

根据您的数据结构(即,如果您在上面的 entity 中有多个匹配项),您可能需要对上面的最后三行执行类似的操作:

for ent in entity:
    if category in ent.categories and get_percentage(ent.tags, tags, 0.8):
        valid_entities.append(ent.entity_id)
return valid_entities

【讨论】:

  • 实际上类别是数据框列中的一个列表,如果其中一个值匹配,我必须匹配该列表,然后我将包含该实体
  • @HammadKhan roger,我根据我认为我理解您的数据结构的内容更新了它......
  • 感谢它现在表现更好:)
【解决方案2】:

第一步是查看 Engineero 的答案,该答案修复了不必要的 if 和 for 循环。接下来,我建议您是否使用大量输入数据,如果它需要花费大量时间,则应该是这种情况。您可能希望使用 numpy 数组而不是列表来存储数据,因为它更适合大量数据 as seen here。 Numpy 甚至击败了 Pandas DataFrames as seen here。在某一点之后,您应该问自己效率是否比使用 Pandas 的便利性更重要,如果是这样,对于大量数据,Numpy 会更快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多