我的代码效率低下还是我的任务很艰难?

时间:2016-06-19 16:17:49

标签: python pandas nltk

希望有人可以在这里帮忙吗?

我已经编写了一些代码来执行查找任务,并且需要花费很长时间才能完成它 - 远远超过它应该的时间。出于保密原因,我无法描述确切的任务,但我可以给出一个直接类似的任务。

假设我有一个包含单词列表和一组与这些单词对应的值的数据库。说,颜色和这些颜色喜欢多少。

现在,我有一个文本,我想将此文本中的所有单词与我的颜色数据库进行比较,如果存在匹配,我会从数据库中提取“喜欢”评级并进行记录。当文本中的所有单词与数据库匹配(或不匹配)时,“喜欢”评级的总和就是我的输出。

相当于我编写的代码如下所示,它适用于我给出的玩具示例。但是,我的实际问题包含一个40k条目的数据库,文本通常有大约500个单词;文本中的大多数单词都将出现在数据库中。当我运行它时,执行需要几个小时。据我所知,对40k条目的数据库匹配500个单词意味着大约20m的比较。还是,小时

任何人都可以建议我是否在硬件有限的情况下进行计算密集型问题,或者我的代码效率是否非常低效?

谢谢!

import pandas as pd
import nltk as nltk

####### Creates toy data to test code on ###

colour = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']
values = [1,2,3,4,5,6,7]

df1 = pd.DataFrame({'colour': ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet']})

df2 = pd.DataFrame({'value': [1,2,3,4,5,6,7]})

dfs = [df1, df2]

###### Code proper begins below

data = pd.concat(dfs, axis = 1) ######## Dataframe


#### Sample words 
words = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet', 'cyan', 'white', 'black', 'pink', 'grey', 'scarlet']


#### Lists into which words are put post-analysis
rating = 0
rated = []
unrated = []

####### Code

for i in words:
    for j in range(len(data['colour'])):
        if i == data['colour'][j]: 
            rating = rating + data['value'][j]
            rated.append(i)
            break
        elif i not in unrated and i not in data.values: ### Ensures each unrated word is entered only once.
            unrated.append(i)

3 个答案:

答案 0 :(得分:2)

您需要为关键字编制索引,以便在O(1)时间内查找文本中的每个单词。如果数据集可以适合内存(并且有40k字应该没问题),它就可以这么简单:

sentiment_index = dict(zip(colour, values))
rated = set()

for i in words:
    i = i.lower()
    rating += sentiment_index.get(i, 0)
    rated.add(i)

你也可以写rating += sentiment_index[i],这同样快。但是你需要一个存在检查,我可以通过get()使用默认值来避免。当然,我为评级词添加了一组。如果确实需要将查找委托给数据库,请向数据框添加索引以加快查找速度。

答案 1 :(得分:0)

让我们从一些数学开始...如果你的数据库中有40,000个条目,你需要检查500个单词(没有特殊的明显规则),你需要进行20,000,000次比较。这不是一项小任务。

其次,假设你正在比较字符串(单词),你也在做一些CASE操作(例如确保“RED”“Red”,“REd”,“ReD”,......,“red”是被认为是相同的价值)。

所以,总而言之,你应该期望至少需要几秒钟。但不是HOURS(除非你使用的是8086处理器: - ))。

最后,您的代码似乎不完整,因此无法检查。

答案 2 :(得分:0)

好的,我从离线的人那里得到了一些建议,这些建议在这里有很大的不同。它可能对任何想要遇到类似问题的人都有用。看来我最大的瓶颈在于:

elif i not in unrated and i not in data.values:

这是因为data.values是一个数组,搜索需要时间。创建变量

words = set(data1['Word'].values)

将数组转换为一个集合并将其放入循环而不是数组中将执行时间从1小时减少到大约3分钟。这仍然很慢,但它比它更好。