在Python数据集中搜索单词模式

在Python数据集中搜索单词模式,python,regex,string,count,Python,Regex,String,Count,我希望我能把这个问题解释清楚。我是一名python实验者(以防下面的查询显得幼稚) 假设我有一个如下形式的数据集: a = ( ('309','308','308'), ('309','308','307'), ('308', '309','306', '304')) 让我将每个('309'、'308'、'308')作为路径调用 我要查找以下各项的计数: a计数('309','308',) b计数('309','308') 以及所有可能的排列 我在想它是某种正则表达式,可以帮助我实现这个搜索。

我希望我能把这个问题解释清楚。我是一名python实验者(以防下面的查询显得幼稚)

假设我有一个如下形式的数据集:

a = ( ('309','308','308'), ('309','308','307'), ('308', '309','306', '304'))
让我将每个
('309'、'308'、'308')
作为路径调用

我要查找以下各项的计数:

a<代码>计数('309','308',)

b<代码>计数('309','308')

以及所有可能的排列

我在想它是某种正则表达式,可以帮助我实现这个搜索。我的路径数达到了50000条

有人能建议我如何用python做这种操作吗?我探索了trie,但我不认为这对我有帮助

谢谢, Sagar

您可以使用它:

>>> from collections import Counter
>>> a = ( ('309','308','308'), ('309','308','307'), ('308', '309','306', '304'))
>>> Counter((x, y) for (x, y, *z) in a)
Counter({('309', '308'): 2, ('308', '309'): 1})
>>> Counter((x, z) for (x, y, z, *w) in a)
Counter({('308', '306'): 1, ('309', '308'): 1, ('309', '307'): 1})
我还在这里使用扩展元组解包,这在Python3.x之前是不存在的,只有当您有长度不确定的元组时才需要。在python 2.x中,您可以执行以下操作:

Counter((item[0], item[1]) for item in a)
然而,我不能说这会有多有效。我认为这不应该是坏事

计数器
具有类似于
dict
的语法:

>>> count = Counter((x, y) for (x, y, *z) in a)
>>> count['309', '308']
2
编辑:您提到它们的长度可能大于1,在这种情况下,您可能会遇到问题,因为如果长度小于所需长度,它们将无法解包。解决方案是将生成器表达式更改为忽略任何非所需格式的表达式:

Counter((item[0], item[1]) for item in a if len(item) >= 2)
例如:

当然,这只适用于连续运行,如果要单独拾取列,则需要做更多的工作:

def pick(seq, indices):
    return tuple([seq[i] for i in indices])

columns = [1, 3]
maximum = max(columns)
Counter(pick(item, columns) for item in a if len(item) > maximum)
您可以使用以下方法执行此操作:

>>> from collections import Counter
>>> a = ( ('309','308','308'), ('309','308','307'), ('308', '309','306', '304'))
>>> Counter((x, y) for (x, y, *z) in a)
Counter({('309', '308'): 2, ('308', '309'): 1})
>>> Counter((x, z) for (x, y, z, *w) in a)
Counter({('308', '306'): 1, ('309', '308'): 1, ('309', '307'): 1})
我还在这里使用扩展元组解包,这在Python3.x之前是不存在的,只有当您有长度不确定的元组时才需要。在python 2.x中,您可以执行以下操作:

Counter((item[0], item[1]) for item in a)
然而,我不能说这会有多有效。我认为这不应该是坏事

计数器
具有类似于
dict
的语法:

>>> count = Counter((x, y) for (x, y, *z) in a)
>>> count['309', '308']
2
编辑:您提到它们的长度可能大于1,在这种情况下,您可能会遇到问题,因为如果长度小于所需长度,它们将无法解包。解决方案是将生成器表达式更改为忽略任何非所需格式的表达式:

Counter((item[0], item[1]) for item in a if len(item) >= 2)
例如:

当然,这只适用于连续运行,如果要单独拾取列,则需要做更多的工作:

def pick(seq, indices):
    return tuple([seq[i] for i in indices])

columns = [1, 3]
maximum = max(columns)
Counter(pick(item, columns) for item in a if len(item) > maximum)

如果您是Python 2.7之前的版本,则可以使用列表理解:

#Number of: ('309','308', <any word>)
>>> len([i[0] for i in a if i[0]=='309' and i[1]=='308'])
2
#Number of:('309',<any word>,'308')
>>> len([i[0] for i in a if i[0]=='309' and i[-1]=='308'])
1

如果您是Python 2.7之前的版本,则可以使用列表理解:

#Number of: ('309','308', <any word>)
>>> len([i[0] for i in a if i[0]=='309' and i[1]=='308'])
2
#Number of:('309',<any word>,'308')
>>> len([i[0] for i in a if i[0]=='309' and i[-1]=='308'])
1


如果您想以CS风格的高效方式实现这一点,您应该查看。您需要稍微修改一下以将每个子树的大小存储在其根上,但这应该不会太难。

如果您想以CS风格的高效方式执行此操作,您应该查看。您需要稍微修改一下以将每个子树的大小存储在其根上,但这应该不会太难。

最后一个元组中应该有四个数字吗?是的。。它可以是任何大于1的数字,而不是我的例子中的3或4。最后一个元组中应该有四个数字吗?是的。。它可以是任何大于1的数字,而不是我示例中的3或4。好的。这个概念看起来很有趣。我从来不知道。所以,我将从一个有50000个路径的文件中读取。然后,我将在循环中使用计数器概念来确定。让我看看怎样才能让它工作。但是,你的帮助太棒了。非常感谢!萨加尔:我添加了一个注释,说明了你关于可能更短元组的观点。如果这回答了你的问题,我有一个新问题。项目[0],项目[1]对我来说是可变的。也就是说,我需要首先计算计数器(项目[0],项目[1])。我不知道编程时项目[I]的编号。有什么想法吗?@Sagar我为更一般的问题添加了一个解决方案。你太棒了!在这个论坛上有什么方法可以推荐你吗?好的。这个概念看起来很有趣。我从来不知道。所以,我将从一个有50000个路径的文件中读取。然后,我将在循环中使用计数器概念来确定。让我看看怎样才能让它工作。但是,你的帮助太棒了。非常感谢!萨加尔:我添加了一个注释,说明了你关于可能更短元组的观点。如果这回答了你的问题,我有一个新问题。项目[0],项目[1]对我来说是可变的。也就是说,我需要首先计算计数器(项目[0],项目[1])。我不知道编程时项目[I]的编号。有什么想法吗?@Sagar我为更一般的问题添加了一个解决方案。你太棒了!有什么方法可以让我在这个论坛上推荐你吗?我确实从效率的角度尝试了trie。实际上,根树是最好的。但是,在使用pytrie和pyradix包的python实现方面,我无法从google获得太多帮助。所以,我失败了。如果我知道它们是如何工作的,我同意它们是最佳解决方案+1,如果您需要最佳性能,这是一个很好的解决方案-但是它需要更多的实现,因此如果简单的
计数器
方法足够快,这才是最重要的。我确实从效率的角度尝试了trie。实际上,根树是最好的。但是,在使用pytrie和pyradix包的python实现方面,我无法从google获得太多帮助。所以,我失败了。如果我知道它们是如何工作的,我同意它们是最佳解决方案+1,如果您需要最佳性能,这是一个很好的解决方案-但是它需要更多的实现,因此如果简单的
计数器
方法足够快,这才是最重要的。