在numpy数组中快速计算字符串出现次数的方法(Python)

5

我有一个包含元组的numpy数组:

trainY = np.array([('php', 'image-processing', 'file-upload', 'upload', 'mime-types'),
                   ('firefox',), ('r', 'matlab', 'machine-learning'),
                   ('c#', 'url', 'encoding'), ('php', 'api', 'file-get-contents'),
                   ('proxy', 'active-directory', 'jmeter'), ('core-plot',),
                   ('c#', 'asp.net', 'windows-phone-7'),
                   ('.net', 'javascript', 'code-generation'),
                   ('sql', 'variables', 'parameters', 'procedure', 'calls')], dtype=object)

我得到了一个索引列表,它可以将这个np.array分成子集:

x = [0, 4]

以及一个字符串:

label = 'php'

我希望能够统计出在这个 np.array 的子集中标签 'php' 出现的次数。在这种情况下,答案是2。

注意:

1)一个标签最多只会出现一次;

2)元组的长度可以为 1 到 5;

3)列表 x 的长度通常为 7-50;

4)trainY 的长度约为 80 万。

我目前用以下代码来实现:

sum([1 for n in x if label in trainY[n]])

这是我程序当前的性能瓶颈,我正在寻找一种方法使其运行更快。我认为我们可以跳过对x的循环,只需像trainY[x]这样进行矢量化查找trainY,但我无法得到有效的结果。

谢谢。


1
你是否在对相同的 trainY 进行多次计算? 你可以考虑对 trainY 进行一些预处理。 - lev
是的,trainY 是相同的。变化的是 label 和索引 x - mchangun
你当前代码的简化版本:sum(label in words for words in trainY[x])。(我不知道这是否会对性能产生太大影响。) - Warren Weckesser
x的长度很小。求和应该立即计算。如果它是您程序中的瓶颈,这意味着您要多次计算总和。请为代码提供上下文。您可能会在那里找到优化机会。如果您删除sum()调用并将其替换为虚拟常量,您的程序会快多少? - jfs
3个回答

6

我认为在这种情况下使用计数器可能是一个不错的选择。

from collections import Counter

c = Counter([i for j in trainY for i in j])

print c['php'] # Returns 2
print c.most_common(5) # Print the 5 most common items.

1
好的回答,只需添加:要打印出原帖作者想要的项目,您可以执行 c['php'] - Saullo G. P. Castro
1
c=Counter([i for j in trainY for i in j])比使用for循环更快。 - Saullo G. P. Castro

2
您可以通过列表推导式展平数组,然后使用np.in1d
trainY = np.array([i for j in trainY for i in j])
ans = np.in1d(trainY, 'php').sum()
# 2

0
考虑构建一个形式为字典的数据结构:
{'string1': (1,2,5),
 'string2': (3,4,5),
 ...
}

对于每个单词,保存一个元组中出现的索引的排序列表。 希望这样说得通...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接