【问题标题】:Group data by a given Range按给定范围对数据进行分组
【发布时间】:2021-12-28 16:09:53
【问题描述】:

我正在寻找一种算法来获得不同值的不同平均值。 例子: 我的值是 1.6、1.7、5.6、5.7、5,5 所以输出应该是 1.65 和 5.7

【问题讨论】:

  • 您使用什么规则来决定哪些值属于哪个?这个问题的答案对于确定使用什么算法很重要。可能是一个非常简单的分组问题,也可能是一个非常复杂的聚类问题。
  • 是否允许使用内置函数,如 reduce 或 group call?
  • 我建议阅读一些关于不同聚类算法的内容,你可以试试他们的implementation in scikit-learn
  • 等等,你已经知道会有两个组了??
  • 好吧,只是对值列表进行排序,寻找最大的差距,然后在最大差距处拆分列表?? [1.6, 1.7, 5.6, 5.7, 5.5] -> 排序 -> [1.6, 1.7, 5.5, 5.6, 5.7] -> 测量差距 -> [0.1, 3.8, 0.1, 0.1] -> 最大差距是第二个差距(3.8) -> [1.6, 1.7] "split here" [5.5, 5.6, 5.7]

标签: python algorithm


【解决方案1】:

如果你知道每个簇周围的“范围”意味着

一个可能的简单解决方案:将每个值四舍五入为“范围”参数的倍数;将四舍五入为相同倍数的值分组。

要进行分组,您可以使用sorteditertools.groupby 的组合,或者更简单地说,您可以使用dictlists

from collections import defaultdict

def clusters(data, r):
    groups = defaultdict(list)
    for x in data:
        groups[x // r].append(x)
    return groups

def means_of_clusters(data, r):
    return [sum(g) / len(g) for g in clusters(data, r).values()]

print( means_of_clusters([1.6, 1.7, 5.6, 5.7, 5.5], 0.4) )
# [1.65, 5.55, 5.7]

请注意 5.7 是如何与 5.5 和 5.6 分开的,因为 5.5 和 5.6 舍入为 13*0.4,而 5.7 舍入为 14*0.4

如果你知道集群的数量

您在 cmets 中提到总会有 2 个集群。我建议只寻找排序列表中两个连续数字之间的最大差距,然后在该差距上进行拆分:

def split_in_2_clusters(data):
    seq = sorted(data)
    split_index = max(range(1, len(seq)), key=lambda i: seq[i] - seq[i-1])
    return seq[:split_index], seq[split_index:]

def means_of_2_clusters(data):
    return tuple(sum(g) / len(g) for g in split_in_2_clusters(data))

print( means_of_2_clusters([1.6, 1.7, 5.6, 5.7, 5.5]) )
# (1.65, 5.6000000000000005)

对于更复杂的聚类问题

我强烈建议查看库 scikit-learn 中实现的所有聚类算法。文档页面在一个漂亮的表格中列出了算法,解释了哪个算法需要哪些参数;因此您可以轻松选择最适合您情况的算法。

【讨论】:

  • 我试过你的代码,但有一点问题。我有一个仪表读数器,它总是在旋转,因此线条可能接近 0 和 9,因此如果指针在 0.1 附近,则附近的指针在 9.9 上,因此它将 9.9 作为最大值。
  • @GetBoosted 所以你是说这些值应该像在一个圆圈上而不是在一条线上一样处理?
  • 假设您有一个指向 0.1 的指针。该指针在刻度上的宽度约为 0.3。然后我的 hoghlines 识别的线也转到 9.9,然后最大距离是从例如5 到 9.9。
  • 是的,它是一个仪表阅读器,数值在一个圆圈上
  • @GetBoosted 如果值围绕一个圆圈,那么您需要找到两个分割点,而不仅仅是一个;并且由于 10 和 0 是等效的,而不是 split_in_two_clusters 函数中的 seq[i] - seq[i-1],您应该使用距离 min(abs(seq[i] - seq[i-1]), 10 - abs(seq[i] - seq[i-1]))
猜你喜欢
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-10
  • 2014-07-23
  • 2020-12-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多