Python 在列表中识别具有相似编号的组
我有一些我想按相似性分组的数字列表。列表中数字的顺序是固定的,必须保留 作为一个例子,下面是我试图实现的一个可视化: 黑线代表我拥有的数字列表。绿线表示我想在这个示例列表中识别的分组 列表中数字的顺序很重要,不能更改(例如,不能按升序或降序排序)。列表中的数字不是连续的(即不可能有Python 在列表中识别具有相似编号的组,python,list,Python,List,我有一些我想按相似性分组的数字列表。列表中数字的顺序是固定的,必须保留 作为一个例子,下面是我试图实现的一个可视化: 黑线代表我拥有的数字列表。绿线表示我想在这个示例列表中识别的分组 列表中数字的顺序很重要,不能更改(例如,不能按升序或降序排序)。列表中的数字不是连续的(即不可能有6,6,6,6,但可能类似5.85,6.1,5.96,5.88) 有没有办法做到这一点 编辑:示例值和所需分组: [4.1,4.05,4.14,4.01,3.97,4.52,4.97,5.02,5.05,5.2,5.
6,6,6,6
,但可能类似5.85,6.1,5.96,5.88
)
有没有办法做到这一点
编辑:示例值和所需分组:
[4.1,4.05,4.14,4.01,3.97,4.52,4.97,5.02,5.05,5.2,5.18,3.66,3.77,3.59,3.72]
将导致一组近似的
[(4.1,4.05,4.14,4.01,3.97,4.52),(4.97,5.02,5.05,5.2,5.18),(3.66,3.77,3.59,3.72)]
在上面的分组中,您可以认为4.52
可能属于第一组或第二组。如果像我在上面的例子中所做的那样进行可视化,分组将由绿线表示。我的列表的长度实际上是几百到几千个值。您可以使用-它将连续元素与给定键函数的相同结果组合在一起(在本例中):
您可以使用
itertools.groupby
根据与前一项的特定差异(2
)对数据进行分类
from itertools import groupby, chain
from collections import OrderedDict
def grouper(_lst, interval):
z = zip(_lst,_lst[1:])
return [OrderedDict.fromkeys(chain.from_iterable(g)).keys() for k,g in groupby(z,key=lambda x:x[1]-x[0]<interval) if k]
这确保了一组中的每个项目不超过该组平均值的max_diff
。如果是,则启动一个新组。numpy版本:
l = [4.1, 4.05, 4.14, 4.01, 3.97, 4.52, 4.97, 5.02, 5.05, 5.2, 5.18, 3.66, 3.77, 3.59, 3.72]
import numpy as np
x = np.array(l)
mask = np.diff(np.round(x))
print(np.split(x, np.where(mask)[0] + 1))
[array([ 4.1 , 4.05, 4.14, 4.01, 3.97]), array([ 4.52, 4.97, 5.02, 5.05, 5.2 , 5.18]), array([ 3.66, 3.77, 3.59, 3.72])]
或:
将numpy导入为np
差异=.5
x=np.数组(l)
mask=np.abs(x[:-1]-x[1:])
k-均值聚类是一种矢量量化方法,起源于信号处理,是数据挖掘中常用的聚类分析方法。k-均值聚类的目的是将n个观测值划分为k个聚类,其中每个观测值都属于具有最近均值的聚类,作为聚类的原型。这将导致将数据空间划分为Voronoi单元格。您应该添加一个可能值的列表以及所需的输出。我已经添加了一个示例列表。@Padraickenningham谢谢。我有一只小虫子。现在已修复。我发现这是最通用的解决方案,谢谢。这不是一个真正有用的答案,尤其是与这里的其他答案相比。
test = [0, 1.3, 2.2, 2.9, 6, 7.8, 8, 9.1, 10.4,15, 16, 17.6, 17.7, 18.9]
print(grouper(test, 2))
[[0, 1.3, 2.2, 2.9], [6, 7.8, 8, 9.1, 10.4], [15, 16, 17.6, 17.7, 18.9]]
from statistics import mean
def ordered_cluster(data, max_diff):
current_group = ()
for item in data:
test_group = current_group + (item, )
test_group_mean = mean(test_group)
if all((abs(test_group_mean - test_item) < max_diff for test_item in test_group)):
current_group = test_group
else:
yield current_group
current_group = (item, )
if current_group:
yield current_group
data = [4.1, 4.05, 4.14, 4.01, 3.97, 4.52, 4.97, 5.02, 5.05, 5.2, 5.18, 3.66, 3.77, 3.59, 3.72]
print(list(ordered_cluster(data, 0.5)))
[(4.1, 4.05, 4.14, 4.01, 3.97, 4.52), (4.97, 5.02, 5.05, 5.2, 5.18), (3.66, 3.77, 3.59, 3.72)]
l = [4.1, 4.05, 4.14, 4.01, 3.97, 4.52, 4.97, 5.02, 5.05, 5.2, 5.18, 3.66, 3.77, 3.59, 3.72]
import numpy as np
x = np.array(l)
mask = np.diff(np.round(x))
print(np.split(x, np.where(mask)[0] + 1))
[array([ 4.1 , 4.05, 4.14, 4.01, 3.97]), array([ 4.52, 4.97, 5.02, 5.05, 5.2 , 5.18]), array([ 3.66, 3.77, 3.59, 3.72])]
import numpy as np
diff = .5
x = np.array(l)
mask = np.abs(x[:-1] - x[1:]) <= diff
print(np.split(x, np.where(~mask)[0] + 1)
[array([ 4.1 , 4.05, 4.14, 4.01, 3.97]), array([ 4.52, 4.97, 5.02, 5.05, 5.2 , 5.18]), array([ 3.66, 3.77, 3.59, 3.72])]