最重要的是:这个问题与其他问题类似,但其他问题的解决方案对我没有帮助。
例如:在 countif 范围中使用数组公式、在 Countif 中使用范围作为条件、使用过滤数据的 CountIf
询问: 我正在一个大表中对两个频率加权变量进行矩阵乘法,这需要大量的过滤。这是我的数据的最小版本,是我想要做的事情的一个工作示例,然后是我想要解决的问题:
行 | A-过滤器1 | B-过滤器2 | C-Var1 | D-Var2 |
---|---|---|---|---|
2 | 1 | 1 | 1 | 10 |
3 | 1 | 1 | 5 | 12 |
4 | 1 | 1 | 1 | 11 |
5 | 1 | 1 | 2 | 12 |
6 | 1 | 1 | 4 | 13 |
7 | 1 | 2 | 5 | 11 |
8 | 1 | 2 | 3 | 12 |
9 | 1 | 2 | 1 | 12 |
10 | 1 | 2 | 2 | 13 |
11 | 1 | 2 | 4 | 14 |
计算步骤如下:
A:Axis1:Var1 唯一值的频率,其中 Filter1=1 乘以 Var1(以获得频率加权 Var1):
SORT(UNIQUE(FILTER($C$2:$C$11, ($A$2:$A$11=1) )))
COUNTIFS($C$2:$C$11, <result of #1>,$A$2:$A$11,1)
<for each of #2> / SUM(<result of #2>)
<result of #1> * <result of #3>
B:Axis2:Var2 的唯一值的频率,其中 Filter1=1 AND Filter2=1 乘以某个值 X 减去 Var2(以获得频率加权的“X - Var2”):
步骤与 Axis #1 完全相同,但添加了额外的 Filter 并从 X 中减去 Var2
C:矩阵乘法:
SUM(<Each ofAxis1:Result #4> * <Each ofAxis2:Result #4>)
D:将步骤 C 乘以 Filter1=1 & Filter2=2 的计数:
<Resulted of Step C> * COUNTIFS($B$2:$B$11, 1, $A$2:$A$11, 1)
此数学运算的目的并不重要,但如果它有助于您理解它,您可以认为 Filter1 = 月,Filter2 = 日,因此我们得出 Var1 的频率加权出现次数的总和一个月内到一天内 Var2,跨越一天内的小时数。
无论如何,我都会为您节省时间并分享一个方程式/函数,它完全符合我上面描述的功能(尽管我需要转置一个轴才能使矩阵乘法发挥作用)。我设置 X = 50:
=SUM(
(
COUNTIFS($C$2:$C$11,
TRANSPOSE(SORT(UNIQUE(FILTER($C$2:$C$11, ($A$2:$A$11=1) )))),
$A$2:$A$11, 1)
/ COUNTIFS($A$2:$A$11, 1)
* TRANSPOSE(SORT(UNIQUE(FILTER($C$2:$C$11, ($A$2:$A$11=1) ))))
)
*
(
COUNTIFS($D$2:$D$11,
SORT(UNIQUE(FILTER($D$2:$D$11, ($B$2:$B$11=1)*($A$2:$A$11=1) ))),
$B$2:$B$11, 1,
$A$2:$A$11, 1)
/ COUNTIFS($B$2:$B$11, 1, $A$2:$A$11, 1)
* (50 - SORT(UNIQUE(FILTER($D$2:$D$11, ($B$2:$B$11=1)*($A$2:$A$11=1) ))) )
)
) * COUNTIFS($B$2:$B$11, 1, $A$2:$A$11, 1)
结果 = 537.6
因此,即使在 100,000 行数据上,它也能很好地工作并且速度超快,这让我想到了我的问题:
以上数据经过简化。除了有两个以上的过滤列(很容易绕过)之外,Var1 和 Var2 本身就是计算字段 AND 也需要进行过滤。
我只关注 Var1,因为两者的解决方案都是相同的:让我们将 Var1 重写为:
Var1 = MAX(3 - Var1, 0)
或者使其更适合数组:Var1 = (Var1<3) * (3-Var1)
如果我们回到上面的更大的公式,这意味着我想要要做的是改变这个:
(
COUNTIFS($C$2:$C$11,
TRANSPOSE(SORT(UNIQUE(FILTER($C$2:$C$11, ($A$2:$A$11=1) )))),
$A$2:$A$11, 1)
/ COUNTIFS($A$2:$A$11, 1)
* TRANSPOSE(SORT(UNIQUE(FILTER($C$2:$C$11, ($A$2:$A$11=1) ))))
)
到
(
COUNTIFS(FILTER(3 - $C$2:$C$11, ($A$2:$A$11=1)*($C$2:$C$11<3) ),
TRANSPOSE(SORT(UNIQUE(FILTER(3 - $C$2:$C$11, ($A$2:$A$11=1)*($C$2:$C$11<3) )))),
$A$2:$A$11, 1)
/ COUNTIFS($A$2:$A$11, 1)
* TRANSPOSE(SORT(UNIQUE(FILTER(3 - $C$2:$C$11, ($A$2:$A$11=1)*($C$2:$C$11<3) ))))
)
结果 = 153.6(使用辅助列)
除了第一行之外,一切正常:
COUNTIFS( FILTER(3 - $C$2:$C$11, ($A$2:$A$11=1)*($C$2:$C$11<3) ), ...
因为显然 COUNTIFS 不会接受数组而不是范围。顺便说一句,使用该公式创建范围是有效的,但前提是您将其设置为等于完整表中包含的值的数量。无论哪种情况,创建“辅助范围”在我的应用程序中都是不切实际的。
我尝试过以数组公式形式输入的
SUM
和 SUMPRODUCT
公式的各种组合,但到目前为止还没有找到获胜的组合。
由于您正在做频率,我建议将 Countifs 替换为频率,如下所示:
=SUM(
(
TRANSPOSE(DROP(FREQUENCY(FILTER(3 - $C$2:$C$11, ($A$2:$A$11=1)*($C$2:$C$11<3) ),
(SORT(UNIQUE(FILTER(3 - $C$2:$C$11, ($A$2:$A$11=1)*($C$2:$C$11<3) ))))),-1))
/ COUNTIFS($A$2:$A$11, 1)
* TRANSPOSE(SORT(UNIQUE(FILTER(3 - $C$2:$C$11, ($A$2:$A$11=1)*($C$2:$C$11<3) ))))
)
*
(
COUNTIFS($D$2:$D$11,
SORT(UNIQUE(FILTER($D$2:$D$11, ($B$2:$B$11=1)*($A$2:$A$11=1) ))),
$B$2:$B$11, 1,
$A$2:$A$11, 1)
/ COUNTIFS($B$2:$B$11, 1, $A$2:$A$11, 1)
* (50 - SORT(UNIQUE(FILTER($D$2:$D$11, ($B$2:$B$11=1)*($A$2:$A$11=1) ))) )
)
) * COUNTIFS($B$2:$B$11, 1, $A$2:$A$11, 1)