寻找 COUNTIFS() 的替代方案,它将与动态范围一起使用(例如:FILTER() 函数的数组输出)

问题描述 投票:0回答:1

最重要的是:这个问题与其他问题类似,但其他问题的解决方案对我没有帮助。

例如:在 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:Axis1Var1 唯一值的频率,其中 Filter1=1 乘以 Var1(以获得频率加权 Var1):

  1. 获取唯一的Var1,并排序
    SORT(UNIQUE(FILTER($C$2:$C$11, ($A$2:$A$11=1) )))
  2. 按值获取#1 的计数
    COUNTIFS($C$2:$C$11, <result of #1>,$A$2:$A$11,1)
  3. 将 #2 表示为 %
    <for each of #2> / SUM(<result of #2>)
  4. 将#1乘以#3得到频率加权Var1
    <result of #1> * <result of #3>

B:Axis2Var2 的唯一值的频率,其中 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
公式的各种组合,但到目前为止还没有找到获胜的组合。

excel excel-formula array-formulas
1个回答
0
投票

由于您正在做频率,我建议将 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)

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.