Excel:查找两个相似的列匹配的紧密程度

我想比较两个有点相似的列,看看他们究竟有多相似(重叠%)。 我的网格大约是600×600,但这里是一个简略的例子。

100 101 102 103 104 105 A 1 1 1 1 1 1 B 1 1 1 1 1 1 C 1 1 1 1 1 1 D 1 1 1 1 E 1 1 1 F 1 G TTL 3 4 4 5 5 5 100% 75% 75% 80% 80% 80% 

我们会说这些是汽车和零件。 网格中的区域是二进制是/否,1 /空白指示符。 车#101和#102都有4个部分,但是他们之间只有3个是相同的,所以他们被认为是75%的相似。 汽车#103和104是完全一样的,但所有的汽车与5个部分,他们只有80%相似。

你将如何去获得这些大数据集的数字? 可能有三十辆“汽车”,其中有600“零件”需要比较。 除百分比外,我拥有所有数据。

这是一个可能的解决scheme。 创build两个命名范围:1)模型 – 它是指包含数字100,101等的标题单元格

2)部分 – 这是包含数字A,B,…的数据左边单元格的单列列。 假设这是在包含1的网格的左边

假设你有两个单元格,比如F15和G15,其中包含数字101或102,在其他单元格中input下面的公式:

 =SUMPRODUCT(OFFSET(parts,0,MATCH(F15,models)),OFFSET(parts,0,MATCH(G15,models)))/SUM(OFFSET(parts,0,MATCH(G15,models))) 

这应该计算由F15和G15中的值所指定的两列中的行数都是1,除以第二列中的1的数目。

如果您在示例中使用像“TTL”这样的助手行,那么只需使用SUMIF即可:

=SUMIF(**TTLRange**, 3)

您只需要将TTLRangereplace为包含总计的单元格即可。

编辑:

您可以在每个现有列之后添加一个帮助器列,使用示例中的数据,此列可以包含:

=IF(A1<>"", A1=C1, FALSE)

然后在另一个帮助行中,在TTL行下面添加以下内容:

=SUMPRODUCT((B1:B7=TRUE)*1)/C8

这个答案中的数据被假定为这种格式:

  ABCDEFG --------------------------------------- 1| 100 101 102 103 104 105 2| A 1 1 1 1 1 1 3| B 1 1 1 1 1 1 4| C 1 1 1 1 1 1 5| D 1 1 1 1 6| E 1 1 1 7| F 1 8| G 9| TTL 3 4 4 5 5 5 10| Similarity 100% 75% 75% 80% 80% 80% 

这个答案涉及一些沉重的math和matrix操纵。 我将深入解释这一点,但首先这里是我使用的公式:

请注意,这是一个input的数组公式: Ctrl + Shift + Enter

式:

 =SUM((MMULT((IF($B$9:$G$9=B9,$B$2:$G$8,($A$2:$A$8>0)*1)),TRANSPOSE(($B$9:$G$9>0)*1))=COUNTA($B$9:$G$9))*1)/B9 

这里是步骤(这是很长的):

步骤1

这一步骤的重点是创build一个只包含相同数量零件的汽车的matrix。 所有其他车辆将有一个1每个部分。 该matrix馈送到步骤#2。

为了解释这一步,我将使用汽车101和102,它们都有四个部分。 使用汽车101和102,我们需要从原始数据中创build这个matrix:

 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 1 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 

除了汽车101和102不具有的部件之外,该matrix每个部件包含1。 这是通过使用公式的内部IF语句来实现的,但是参考零件101或102的C9或D9:

 =IF($B$9:$G$9=C9,$B$2:$G$8,($A$2:$A$8>0)*1) or =IF($B$9:$G$9=D9,$B$2:$G$8,($A$2:$A$8>0)*1) 

它的工作方式是首先为IF语句创build一个真/假值的数组:

 $B$9:$G$9=D9 => {FALSE,TRUE,TRUE,FALSE,FALSE,FALSE} 

使用它可以确定要么查看$ B $ 2:$ G $ 8(对于真实案例)或($ A $ 2:$ A $ 8> 0)* 1(对于假案例)。 考虑$ B $ 2:$ G $ 8将返回相应范围的车辆,在这种情况下,它将产生$C$2:$C$8$D$2:$D$8 。 对于所有的错误情况,它将创build一个数组1的大小,列A列出了多less部分。由于这个例子有7个部分,这将产生每个{1,1,1,1,1,1,1}假案件。 把所有这些放在一起创造了新的matrix。


第2步

这一步我们需要为前一个matrix中的每一行创build一个总和。 为了做到这一点与matrix操作,我们需要乘以每个汽车(包括那些具有不同数量的零件)的数组1的matrix。

继续我们的汽车101和102的例子,我们需要执行这个:

 1 + 1 + 1 + 1 + 1 + 1 = 6 1 + 1 + 1 + 1 + 1 + 1 = 6 1 + 1 + 1 + 1 + 1 + 1 = 6 1 + 1 + 0 + 1 + 1 + 1 = 5 1 + 0 + 1 + 1 + 1 + 1 = 5 1 + 0 + 0 + 1 + 1 + 1 = 4 1 + 0 + 0 + 1 + 1 + 1 = 4 

这是用matrix乘法完成的:

  __ __ _ _ |1 1 1 1 1 1| | 1 | 1x1 + 1x1 + 1x1 + 1x1 + 1x1 + 1x1 = 6 |1 1 1 1 1 1| | 1 | 1x1 + 1x1 + 1x1 + 1x1 + 1x1 + 1x1 = 6 |1 1 1 1 1 1| | 1 | 1x1 + 1x1 + 1x1 + 1x1 + 1x1 + 1x1 = 6 |1 1 0 1 1 1| X | 1 | => 1x1 + 1x1 + 0x1 + 1x1 + 1x1 + 1x1 = 5 |1 0 1 1 1 1| | 1 | 1x1 + 0x1 + 1x1 + 1x1 + 1x1 + 1x1 = 5 |1 0 0 1 1 1| | 1 | 1x1 + 0x1 + 0x1 + 1x1 + 1x1 + 1x1 = 4 |1 0 0 1 1 1| ‾ ‾ 1x1 + 0x1 + 0x1 + 1x1 + 1x1 + 1x1 = 4 ‾‾ ‾‾ 

由于我们已经有了第一个matrix,为了创build1的单列,我们需要看看我们有多less辆车。 这很容易通过参考汽车范围或TTL范围(只要没有任何零部件的汽车)。 在这个例子中,我使用了TTL。 只需拨打($ B $ 9:$ G $ 9> 0)* 1即可获得单行的{1,1,1,1,1,1} 。 然后用TRANSPOSE将它包裹成一 。 然后使用MMULT来乘以两个:

 MMULT((IF($B$9:$G$9=B9,$B$2:$G$8,($A$2:$A$8>0)*1)),TRANSPOSE(($B$9:$G$9>0)*1)) 

第3步

现在开始变得非常简单。 我们只需要计算单个列matrix内有多less个值等于最大车辆数量。 要获得汽车的数量,您可以在TTL行或汽车#行上对此进行硬编码,也可以仅对COUNTA进行编码。 我再次使用TTL:

 COUNTA($B$9:$G$9) 

只需在SUM内使用这个条件(将它乘以1得到1和0)即可得到总数:

 SUM((MMULT(...)=COUNTA($B$9:$G$9))*1) 

在这个继续的例子中,看起来像:

 6 =? 6 => 1 6 =? 6 => 1 6 =? 6 => 1 5 =? 6 => 0 5 =? 6 => 0 4 =? 6 => 0 4 =? 6 => 0 SUM = 3 

步骤4

最后也是最简单的:把这个计数除以该车的零件数量(TTL)来得到百分比。

 SUM((MMULT(...)=COUNTA($B$9:$G$9))*1)/B9 = (3 / 4) = 0.75 => 75% 

下面是一个清晰的截图:

最终产出


您当然需要根据您的数据更新您的范围。

要添加更多的汽车改变所有的水平范围:

 =SUM((MMULT((IF($B$9:$G$9=B9,$B$2:$G$8,($A$2:$A$8>0)*1)),TRANSPOSE(($B$9:$G$9>0)*1))=COUNTA($B$9:$G$9))*1)/B9 ^^^^^^^^^ ^^ ^^ ^^^^^^^^^ ^^ ^^ 

要添加更多的零件,请更改所有垂直范围

 =SUM((MMULT((IF($B$9:$G$9=B9,$B$2:$G$8,($A$2:$A$8>0)*1)),TRANSPOSE(($B$9:$G$9>0)*1))=COUNTA($B$9:$G$9))*1)/B9 ^^ ^^ ^ ^^ ^^^^ ^^ ^^ ^^ ^^ ^