Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中最有效的直方图代码_Python_Performance_Histogram_Tf Idf - Fatal编程技术网

python中最有效的直方图代码

python中最有效的直方图代码,python,performance,histogram,tf-idf,Python,Performance,Histogram,Tf Idf,我已经看到了一些关于在干净的一行程序中制作直方图的问题,但我还没有发现有人试图尽可能高效地制作直方图。我目前正在为一个搜索算法创建很多tfidf向量,这涉及到创建大量直方图和我当前的代码,而非常简短和可读性并没有我想要的那么快。可悲的是,我尝试了许多其他方法,结果慢得多。你能快点吗?cleanStringVector是一个字符串列表(全小写,无标点符号),masterWordList也是一个单词列表,应该包含cleanStringVector中的每个单词 from collections imp

我已经看到了一些关于在干净的一行程序中制作直方图的问题,但我还没有发现有人试图尽可能高效地制作直方图。我目前正在为一个搜索算法创建很多tfidf向量,这涉及到创建大量直方图和我当前的代码,而非常简短和可读性并没有我想要的那么快。可悲的是,我尝试了许多其他方法,结果慢得多。你能快点吗?cleanStringVector是一个字符串列表(全小写,无标点符号),masterWordList也是一个单词列表,应该包含cleanStringVector中的每个单词

from collections import Counter
def tfidfVector(cleanStringVector, masterWordList):
    frequencyHistogram = Counter(cleanStringVector)
    featureVector = [frequencyHistogram[word] for word in masterWordList]
    return featureVector
值得注意的是,计数器对象为不存在的键返回零,而不是引发KeyError,这是一个严重的优点,其他问题中的大多数直方图方法都无法通过此测试

示例:如果我有以下数据:

["apple", "orange", "tomato", "apple", "apple"]
["tomato", "tomato", "orange"]
["apple", "apple", "apple", "cucumber"]
["tomato", "orange", "apple", "apple", "tomato", "orange"]
["orange", "cucumber", "orange", "cucumber", "tomato"]
以及以下主要词表:

["apple", "orange", "tomato", "cucumber"]
我希望从每个测试用例中分别返回以下内容:

[3, 1, 1, 0]
[0, 1, 2, 0]
[3, 0, 0, 1]
[2, 2, 2, 0]
[0, 2, 1, 2]
我希望这有帮助

近似最终结果:

Original Method: 3.213
OrderedDict: 5.529
UnorderedDict: 0.190

使用Python 3,这将我的非代表性微基准测试中的运行时提高了1个数量级:

mapping = dict((w, i) for i, w in enumerate(masterWordList))

def tfidfVector(cleanStringVector, masterWordList):    
    featureVector = [0] * len(masterWordList)
    for w in cleanStringVector:
        featureVector[mapping[w]] += 1
    return featureVector

我认为循环浏览主单词列表是一个问题。每次制作直方图时,都必须对主单词列表中的每个单词进行散列(大多数散列都丢失了,返回0的计算代价很高)

我会先对主单词列表进行散列,然后使用该散列创建每个直方图,这样您只需要对stringvector中的每个单词进行散列(两次,一次获取计数,一次重置主单词列表散列)。如果StringVector小于主单词列表,则会导致哈希操作大大减少:

from itertools import repeat

stringvecs=[["apple", "orange", "tomato", "apple", "apple"],
["tomato", "tomato", "orange"],
["apple", "apple", "apple", "cucumber"],
["tomato", "orange", "apple", "apple", "tomato", "orange"],
["orange", "cucumber", "orange", "cucumber", "tomato"]]

m=["apple", "orange", "tomato", "cucumber"]

md = dict(zip(m, repeat(0)))

def tfidfVector(stringvec, md):
    for item in stringvec:
        md[item]+=1
    out=md.values()
    for item in stringvec:
        md[item]=0
    return out

for stringvec in stringvecs:
    print tfidfVector(stringvec, md)

注意:md.values()应该是稳定的,只要我们不添加键。

cleanStringVector是什么样子的?哦,它只是一个字符串列表。现在是一个简单的python列表,但如果您愿意,可以假设它是一个numpy数组。您对这些方法进行了基准测试吗?我已经运行了大多数方法,而不是所有方法。我删除了一些完全不可读的内容。这似乎是其中最快的,但还是很慢。你看到了吗?虽然关于信件,这些方法可能很有用。我在回答中试图实现的想法是一样的。。但是要优雅得多(也许更快),哦,太棒了。在调用它的代码中对缓存局部性做了一些小的调整,并设法将速度提高了20倍左右。我喜欢这个想法,但它比当前的实现慢得多。(大约需要两倍的时间)是的,我刚刚检查过,使用
orderedict
比使用
dict
慢10倍,而且没有必要,在没有
orderedict
的情况下进行测试这接近Thomas Jung的答案,但仍然有点慢。