Python 基于共性对字符串数组进行分类
我有一个巨大的多词字符串列表。我想根据这些字符串之间的单词匹配数组对这些字符串进行分组。我想不出一个低计算时间的算法 AB 500 巴士AB 500 新闻CA 新闻等等 我的计划是 A.将它们标记为单词。 B创建一个全局数组标记 C将这些字符串与常用标记进行比较 正如你所猜测的,这没有帮助。你能建议一个算法吗?Python 基于共性对字符串数组进行分类,python,string,algorithm,classification,Python,String,Algorithm,Classification,我有一个巨大的多词字符串列表。我想根据这些字符串之间的单词匹配数组对这些字符串进行分组。我想不出一个低计算时间的算法 AB 500 巴士AB 500 新闻CA 新闻等等 我的计划是 A.将它们标记为单词。 B创建一个全局数组标记 C将这些字符串与常用标记进行比较 正如你所猜测的,这没有帮助。你能建议一个算法吗? 我正在用python写这篇文章。你是说这样的东西吗 >>> from collections import defaultdict >>> L=["A
我正在用python写这篇文章。你是说这样的东西吗
>>> from collections import defaultdict
>>> L=["AB 500",
... "Bus AB 500",
... "News CA",
... "News CA BLAH"]
>>> d=defaultdict(list)
>>> for s in L:
... for w in s.split():
... d[w].append(s)
...
>>> print d["News"]
['News CA', 'News CA BLAH']
>>> print d["CA"]
['News CA', 'News CA BLAH']
>>> print d["500"]
['AB 500', 'Bus AB 500']
你是说像这样的事吗
>>> from collections import defaultdict
>>> L=["AB 500",
... "Bus AB 500",
... "News CA",
... "News CA BLAH"]
>>> d=defaultdict(list)
>>> for s in L:
... for w in s.split():
... d[w].append(s)
...
>>> print d["News"]
['News CA', 'News CA BLAH']
>>> print d["CA"]
['News CA', 'News CA BLAH']
>>> print d["500"]
['AB 500', 'Bus AB 500']
20万不是那么多,你可以这么做 拆分每个字符串以获取令牌 e、 g.新闻CA等等->[等等,CA,新闻] 按列表的每一长度创建一个dict条目,例如,在[Blah,CA,News]的情况下,按顺序创建所有组合 现在,只需循环通过dict并查看组 示例代码:
data="""AB 500
Bus AB 500
News CA
News CA BLAH"""
def getCombinations(tokens):
count = len(tokens)
for L in range(1,count+1):
for i in range(count-L+1):
yield tuple(tokens[i:i+L])
groupDict = {}
for s in data.split("\n"):
tokens = s.split()
for groupKey in getCombinations(tokens):
if groupKey not in groupDict:
groupDict[groupKey] = [s]
else:
groupDict[groupKey].append(s)
for group, values in groupDict.iteritems():
if len(values) > 1:
print group, "->", values
它输出:
('News', 'CA') -> ['News CA', 'News CA BLAH']
('AB',) -> ['AB 500', 'Bus AB 500']
('500',) -> ['AB 500', 'Bus AB 500']
('CA',) -> ['News CA', 'News CA BLAH']
('AB', '500') -> ['AB 500', 'Bus AB 500']
('News',) -> ['News CA', 'News CA BLAH']
20万不是那么多,你可以这么做 拆分每个字符串以获取令牌 e、 g.新闻CA等等->[等等,CA,新闻] 按列表的每一长度创建一个dict条目,例如,在[Blah,CA,News]的情况下,按顺序创建所有组合 现在,只需循环通过dict并查看组 示例代码:
data="""AB 500
Bus AB 500
News CA
News CA BLAH"""
def getCombinations(tokens):
count = len(tokens)
for L in range(1,count+1):
for i in range(count-L+1):
yield tuple(tokens[i:i+L])
groupDict = {}
for s in data.split("\n"):
tokens = s.split()
for groupKey in getCombinations(tokens):
if groupKey not in groupDict:
groupDict[groupKey] = [s]
else:
groupDict[groupKey].append(s)
for group, values in groupDict.iteritems():
if len(values) > 1:
print group, "->", values
它输出:
('News', 'CA') -> ['News CA', 'News CA BLAH']
('AB',) -> ['AB 500', 'Bus AB 500']
('500',) -> ['AB 500', 'Bus AB 500']
('CA',) -> ['News CA', 'News CA BLAH']
('AB', '500') -> ['AB 500', 'Bus AB 500']
('News',) -> ['News CA', 'News CA BLAH']
除非单词的重复是用例的一个重要特性,否则我建议使用集合。即:
thestrings = [
"AB 500",
"Bus AB 500",
"News CA",
"News CA BLAH",
]
thesets = dict((s, set(s.split())) for s in thestrings)
similarities = dict()
for s in thestrings:
for o in thestrings:
if s>=o: continue
sims = len(thesets[s] & thesets[o])
if not sims: continue
similarities[s, o] = sims
for s, o in sorted(similarities, similarities.get, reverse=True):
print "%-16r %-16r %2d" % (s, o, similarities[s, o])
这和你要找的差不多吗?它确实按照您希望的方式对您提供的4个字符串进行了分类,但是这是一个非常弱的示例,当然,所以我在重复检查;- 除非单词的重复是用例的一个重要特性,否则我建议使用集合。即:
thestrings = [
"AB 500",
"Bus AB 500",
"News CA",
"News CA BLAH",
]
thesets = dict((s, set(s.split())) for s in thestrings)
similarities = dict()
for s in thestrings:
for o in thestrings:
if s>=o: continue
sims = len(thesets[s] & thesets[o])
if not sims: continue
similarities[s, o] = sims
for s, o in sorted(similarities, similarities.get, reverse=True):
print "%-16r %-16r %2d" % (s, o, similarities[s, o])
这和你要找的差不多吗?它确实按照您希望的方式对您提供的4个字符串进行了分类,但是这是一个非常弱的示例,当然,所以我在重复检查;- 如果将字符串AB 500 News CA添加到您的列表中,会发生什么?这两组字符串必须合并吗?如果没有,如何分割字符串列表,为什么 如果我理解正确,针对此类问题的非常通用的工作流如下所示: 通过反向索引获取候选对的列表// 为每对计算一些距离函数,并将它们组合成一个权重 每个加权对a、b、权重现在表示图中的一条边,您可以通过层次聚类/幂迭代将其聚类到单词匹配组中
如果字符串AB 500 News CA添加到您的列表中,会发生什么?这两组字符串必须合并吗?如果没有,如何分割字符串列表,为什么 如果我理解正确,针对此类问题的非常通用的工作流如下所示: 通过反向索引获取候选对的列表// 为每对计算一些距离函数,并将它们组合成一个权重 每个加权对a、b、权重现在表示图中的一条边,您可以通过层次聚类/幂迭代将其聚类到单词匹配组中
假设三个字符串News CA,News which,News CA which,它们是如何分组的?它们都是组新闻的一部分,然后还有子组?这有点不明确。如果输入还包括总线AB、总线CD 500和总线AB 201怎么办?哪一组是什么?打算根据匹配标记的数量和标记的长度进行评分假设三个字符串新闻CA,新闻CA,新闻CA,它们是如何分组的?它们都是组新闻的一部分,然后还有子组?这有点不明确。如果输入还包括总线AB、总线CD 500和总线AB 201怎么办?哪一组是什么?打算根据匹配的令牌数量和令牌长度进行评分。这将非常缓慢,正如OP所说的200000个字符串,意味着循环40000百万次。是在**2上,但如果它接近OP所希望的,那么它是优化的简单基础,包括算法优化和启发式优化。目前的问题还没有确定;-。这将是非常缓慢的,正如OP所说的200000个字符串,意味着循环4亿次是的,它在**2上,但如果它接近OP所希望的,那么它是一个简单的优化基础,包括算法优化和启发式优化。目前的问题还没有确定;-。