【发布时间】:2025-11-24 17:25:01
【问题描述】:
首先,这不是重复的帖子;我的问题与我在本网站上搜索的问题不同,但如果您发现已回答的问题,请随时链接
说明:
如果您认为您自己的想法如何在下面的 A 和 B 中发现 10 和 2.10 是不接近的第一个元素,这就是我正在尝试以编程方式执行的操作。硬编码阈值不是最佳选择。当然,这里我们需要一个阈值,但是函数应该根据提供的值找到阈值,所以对于 A,阈值可能在 1.1 左右,对于 B,阈值可能在 0.01 左右。如何?那么,“这很有意义”对吗?我们查看了这些值并弄清楚了。这就是我的意思,“动态阈值”本身,如果您的答案包括使用阈值。
A = [1.1, 1.02, 2.3, 10, 10.01, 10.1, 12, 16, 18, 18]
B = [1.01, 1.02, 1.001, 1.03, 2.10, 2.94, 3.01, 8.99]
Python 问题:
我在 Python 中有一个 2D 列表,如下所示,现在如果想要缩小距离较近的项目,仅从上到下开始(列表已经排序,如您所见),我们可以轻松发现前四个比第四个和第五个更接近。
subSetScore = [
['F', 'H', 0.12346022214809049],
['C', 'E', 0.24674283702138702],
['C', 'G', 0.24675055907681284],
['E', 'G', 0.3467125665641178],
['B', 'D', 0.4720531092083966],
['A', 'H', 0.9157739970594413],
['A', 'C', 0.9173801845880128],
['A', 'G', 0.9174496830868454],
['A', 'B', 0.918924595673178],
['A', 'F', 0.9403919097569715],
['A', 'E', 0.9419672090638398],
['A', 'D', 0.9436390340635308],
['B', 'H', 1.3237456293166292],
['D', 'H', 1.3237456293166292],
['D', 'F', 1.3238460160371646],
['B', 'C', 1.3253518168452008],
['D', 'E', 1.325421315344033],
['D', 'G', 1.325421315344033],
['B', 'F', 1.349344243053239],
['B', 'E', 1.350919542360107],
['B', 'G', 1.350919542360107],
['C', 'H', 1.7160260449485403],
['E', 'H', 1.7238716532611786],
['G', 'H', 1.7238716532611786],
['E', 'F', 1.7239720399817142],
['C', 'F', 1.7416246586851503],
['C', 'D', 1.769389308968704],
['F', 'G', 2.1501908892101267]
]
结果:
closest = [
['F', 'H', 0.12346022214809049],
['C', 'E', 0.24674283702138702],
['C', 'G', 0.24675055907681284],
['E', 'G', 0.3467125665641178],
['B', 'D', 0.4720531092083966]
]
与我在这里观察到的其他问题相反,其中给出了 1D 或 2D 列表和任意值,比如说 0.9536795380033108,那么函数必须找到 0.9436390340635308 是最接近列表的,并且大多数解决方案使用绝对差来计算,但这里好像不适用。
一种似乎部分可靠的方法是计算累积差异,如下所示。
consecutiveDifferences = []
for index, item in enumerate(subSetScore):
if index == 0:
continue
consecutiveDifferences.append([index, subSetScore[index][2] - subSetScore[index - 1][2]])
这给了我以下信息:
consecutiveDifferences = [
[1, 0.12328261487329653],
[2, 7.722055425818386e-06],
[3, 0.09996200748730497],
[4, 0.1253405426442788],
[5, 0.4437208878510447],
[6, 0.0016061875285715566],
[7, 6.949849883253201e-05],
[8, 0.0014749125863325885],
[9, 0.021467314083793543],
[10, 0.001575299306868283],
[11, 0.001671824999690985],
[12, 0.3801065952530984],
[13, 0.0],
[14, 0.00010038672053536146],
[15, 0.001505800808036195],
[16, 6.949849883230996e-05],
[17, 0.0],
[18, 0.0239229277092059],
[19, 0.001575299306868061],
[20, 0.0],
[21, 0.36510650258843325],
[22, 0.007845608312638364],
[23, 0.0],
[24, 0.00010038672053558351],
[25, 0.01765261870343604],
[26, 0.027764650283553793],
[27, 0.38080158024142263]
]
现在,大于第 0 个索引的差异的索引是我的截止索引,如下所示:
cutoff = -1
for index, item in enumerate(consecutiveDifferences):
if index == 0:
continue
if consecutiveDifferences[index][1] > consecutiveDifferences[0][1]:
cutoff = index
break
cutoff = cutoff+1
closest = subSetScore[:cutoff+1]
我的列表(最接近)如下:
consecutiveDifferences = [
['F', 'H', 0.12346022214809049],
['C', 'E', 0.24674283702138702],
['C', 'G', 0.24675055907681284],
['E', 'G', 0.3467125665641178],
['B', 'D', 0.4720531092083966]
]
但显然这个逻辑是有问题的,它不适用于以下场景:
subSetScore = [
['A', 'C', 0.143827143333704],
['A', 'G', 0.1438310043614169],
['D', 'F', 0.15684652878164498],
['B', 'H', 0.1568851390587741],
['A', 'H', 0.44111469414482873],
['A', 'F', 0.44121508086536443],
['A', 'E', 0.4441224347331875],
['A', 'B', 0.4465394380814708],
['A', 'D', 0.4465394380814708],
['D', 'H', 0.7595452327118624],
['B', 'F', 0.7596456194323981],
['B', 'E', 0.7625529733002212],
['D', 'E', 0.7625529733002212],
['B', 'C', 0.7635645625610041],
['B', 'G', 0.763661088253827],
['D', 'G', 0.763661088253827],
['B', 'D', 0.7649699766485044],
['C', 'G', 0.7891593152699012],
['G', 'H', 1.0785858136575361],
['C', 'H', 1.0909217972002916],
['C', 'F', 1.0910221839208274],
['C', 'E', 1.0939295377886504],
['C', 'D', 1.0963465411369335],
['E', 'H', 1.3717343427604187],
['E', 'F', 1.3718347294809543],
['E', 'G', 1.3758501983023834],
['F', 'H', 2.0468234552800326],
['F', 'G', 2.050939310821997]
]
由于截止值为 2,因此最接近的如下所示:
closest = [
['A', 'C', 0.143827143333704],
['A', 'G', 0.1438310043614169],
['D', 'F', 0.15684652878164498]
]
但这是预期的结果:
closest = [
['A', 'C', 0.143827143333704],
['A', 'G', 0.1438310043614169],
['D', 'F', 0.15684652878164498],
['B', 'H', 0.1568851390587741]
]
更多数据集:
subSetScore1 = [
['A', 'C', 0.22406316023573888],
['A', 'G', 0.22407088229116476],
['D', 'F', 0.30378179942424355],
['B', 'H', 0.3127393837182006],
['A', 'F', 0.4947366470217576],
['A', 'H', 0.49582931786451195],
['A', 'E', 0.5249800770970015],
['A', 'B', 0.6132933639744492],
['A', 'D', 0.6164207964219085],
['D', 'H', 0.8856811470650012],
['B', 'F', 0.8870402288199465],
['D', 'E', 0.916716087821392],
['B', 'E', 0.929515394689697],
['B', 'C', 1.0224773589334915],
['D', 'G', 1.0252457158036496],
['B', 'G', 1.0815974152736079],
['B', 'D', 1.116948985013035],
['G', 'H', 1.1663971669323054],
['C', 'F', 1.1671269011700458],
['C', 'G', 1.202339473911808],
['C', 'H', 1.28446739439317],
['C', 'E', 1.4222597514115916],
['E', 'F', 1.537160075120155],
['E', 'H', 1.5428705351075527],
['C', 'D', 1.6198555666753154],
['E', 'G', 1.964274682777963],
['F', 'H', 2.3095586690883034],
['F', 'G', 2.6867154391687365]
]
subSetScore2 = [
['A', 'H', 0.22812496138972285],
['A', 'C', 0.23015200093900193],
['A', 'B', 0.2321751794605681],
['A', 'G', 0.23302074452969593],
['A', 'D', 0.23360762074205865],
['A', 'F', 0.24534900601702558],
['A', 'E', 0.24730268603975933],
['B', 'F', 0.24968107911091342],
['B', 'E', 0.2516347591336472],
['B', 'H', 0.2535228016852614],
['B', 'C', 0.25554984123454044],
['C', 'F', 0.2766387746024686],
['G', 'H', 0.2767739105724205],
['D', 'F', 0.2855654706747223],
['D', 'E', 0.28751915069745604],
['D', 'G', 0.30469686299220383],
['D', 'H', 0.30884360675587186],
['E', 'F', 0.31103280946909323],
['E', 'H', 0.33070474566638247],
['B', 'G', 0.7301435066780336],
['B', 'D', 0.7473019138342167],
['C', 'E', 0.749630113545103],
['C', 'H', 0.7515104340412913],
['F', 'H', 0.8092791306818884],
['E', 'G', 0.8506307374871814],
['C', 'G', 1.2281311390340637],
['C', 'D', 1.2454208211324858],
['F', 'G', 1.3292051225026873]
]
subSetScore3 = [
['A', 'F', 0.06947533266614773],
['B', 'F', 0.06947533266614773],
['C', 'F', 0.06947533266614773],
['D', 'F', 0.06947533266614773],
['E', 'F', 0.06947533266614773],
['A', 'H', 0.07006993093393628],
['B', 'H', 0.07006993093393628],
['D', 'H', 0.07006993093393628],
['E', 'H', 0.07006993093393628],
['G', 'H', 0.07006993093393628],
['A', 'E', 0.09015499709650715],
['B', 'E', 0.09015499709650715],
['D', 'E', 0.09015499709650715],
['A', 'C', 0.10039444259115113],
['A', 'G', 0.10039444259115113],
['B', 'C', 0.10039444259115113],
['D', 'G', 0.10039444259115113],
['A', 'D', 0.1104369756724366],
['A', 'B', 0.11063388808579513],
['B', 'G', 2.6511978452376543],
['B', 'D', 2.6612403783189396],
['C', 'H', 2.670889086573508],
['C', 'E', 2.690974152736078],
['C', 'G', 5.252017000877225],
['E', 'G', 5.252017000877225],
['C', 'D', 5.262059533958511],
['F', 'H', 5.322704696245228],
['F', 'G', 10.504651766188518]
]
在不使用任何库(NumPy 和 SciPy 除外)的情况下,我应该如何修复它?
请注意:我使用的是 Python 2.7,任何作为 Python 一部分的库(例如 itertools、operator、math 等)都可以使用。
更新: 我可以使用 SciPy,但不确定没有集群会有什么影响,所以我认为 2 可能就足够了,但无论如何我都不是集群方面的专家,请随时提出建议,不胜感激!
【问题讨论】:
-
如何判断两个元素是否接近?只是数字吗?您是否尝试过 k-means 聚类?
-
我建议你看看聚类算法以及如何使用 Numpy 实现它们。聚类算法基本上根据您指定的标准对彼此相似的项目进行分组。有很多聚类算法 - K-means 是最流行的算法之一。 (注意:如果你愿意使用 scipy 库,你会发现 k-means 已经实现为一个函数,你只需要调用它。它可以让你免于重新发明*的麻烦.)
-
即使 Kmeans 也不够,因为问题似乎非常模糊。不想在这方面考虑太多,但采用百分比差异并尝试对其分布进行建模以发现异常可能有助于自动识别差异
-
好建议!我认为这只能通过 Pycluster 实现
-
Vivek,另一个很棒的建议。但由于这是动态数据,百分比差异阈值的 X% 可能对一个问题有意义,但对另一个问题则没有意义。我似乎无法用同一根棍子统治他们。
标签: list python-2.7