我有数据列表,我想根据相似性进行分组。列表中的数字顺序是固定的,对于保存很重要。
作为一个例子,这里是我想要实现的目标的可视化:
黑线表示我拥有的数字列表。绿线表示我想在此示例列表中标识的分组。
列表中的数字顺序很重要,无法更改(例如,无法按升序或降序排序)。列表中的数字不是连续的(即不可能有 if indexPath.row < facebookPics.count {
if let imgData = NSData(contentsOfURL: self.facebookPics[indexPath.row]){
let image = UIImage(data: imgData)
collectionCell.collectionViewImage.image = image
}
}
的列表,但可能类似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)]
可能属于第一组或第二组。如果像我在上面的示例中所做的那样可视化,则分组将由绿线表示。我的列表实际上是几百到几千个值。
答案 0 :(得分:4)
您可以使用itertools.groupby
- 它将连续元素与给定键函数的结果相同(在这种情况下为round
):
In [7]: import itertools
In [8]: 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]
In [9]: [tuple(xs) for _, xs in itertools.groupby(data, round)]
Out[9]:
[(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)]
答案 1 :(得分:3)
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)]
这可确保组中的每个项目不超过max_diff
到组的平均值。如果是,则启动新组。
答案 2 :(得分:2)
您可以使用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]
我在这里使用了OrderedDict.fromkeys
来保存特定订单中的唯一商品。
演示:
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]]
答案 3 :(得分:2)
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])]
或者:
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])]
答案 4 :(得分:1)
<强> https://en.wikipedia.org/wiki/K-means_clustering 强> k均值聚类是一种矢量量化方法,最初来自信号处理,是数据挖掘中聚类分析的常用方法。 k均值聚类的目的是将n个观测值划分为k个聚类,其中每个观测值属于具有最近均值的聚类,作为聚类的原型。这导致数据空间划分为Voronoi单元。