等了近一年的两个新函数终于发布了,一起来学习吧!

会飞的鱼

KVP函数专家、创作者俱乐部成员

8月26日,WPS 32位正式版更新到了18166。本次更新中,我们期待已久的两个函数——GROUPBY和PIVOTBY终于加入了。接下来,我将为大家介绍这两个函数的具体用法。

GROUPBY函数

函数语法

一、基础用法

1.1、根据姓名对数量汇总

=GROUPBY(B2:B15,C2:C15,SUM)

1.2、根据月份和姓名对数量汇总

=GROUPBY(B2:C15,D2:D15,SUM)

GRPUPBY函数的第1个参数行字段和第2个参数值字段可以引用多列单元格区域或多列的数组。

1.3、根据月份和姓名对数量和金额汇总

=GROUPBY(B2:C15,HSTACK(D2:D15,F2:F15),SUM)
=GROUPBY(B2:C15,CHOOSECOLS(D2:F15,1,3),SUM)

当需要计算的行字段或值字段的多列单元格区域或多列数组不是连续的时,可以使用HSATCK函数拼接,或使用CHOOSECOLS函数返回指定列。

1.4、根据姓名对数量进行求和、计数和求最大值。

=GROUPBY(B2:B15,C2:C15,HSTACK(SUM,COUNT,MAX))

1.5、根据姓名对数量求和、对单价求最大值。

=GROUPBY(B2:B15,C2:D15,HSTACK(SUM,MAX))

当值字段为多列时,可以根据值字段列数使用HSTACK函数依次拼接多个不同函数名称,对多列进行不同的计算。

二、标题

2.1、显示单列标题

=GROUPBY(B1:B15,C1:C15,SUM,3)

行字段和值字段参数引用的单元格区域或数组包含标题时,函数第4个参数设置3即可显示标题。

2.2、显示多列标题

=GROUPBY(B1:C15,D1:E15,SUM,3)

行字段和值字段包含多列时,可以显示多列标题。

2.3、自定义标题

=GROUPBY(B1:C15,D1:E15,VSTACK(HSTACK(SUM,MAX),HSTACK("手机合计","电脑最大值")),3)

使用HSTACK函数横向拼接多个自定义函数标题,然后使用VSTACK函数拼接计算函数名称,即可实现添加自定义标题。

三、排序

GROUPBY函数第6个参数可以控制汇总后返回数据的排序,根据行字段和值字段返回的总列数,正数为升序,负数为降序。

3.1、根据数量降序排序

=GROUPBY(B2:B15,C2:C15,SUM,,,-2)

行字段和值字段共2列,将GROUPBY函数第6个参数设置-2,即可实现对返回数据降序排序。

3.2、对行字段进行多列排序

=GROUPBY(B2:C15,D2:D15,SUM,,,{-1,2})
=GROUPBY(B2:C15,D2:D15,SUM,,,HSTACK(-1,2))

当行字段有多列时,可以使用常量数组,或使用HSTACK函数拼接多个排序参数,可以对行字段进行多条件排序。

3.3、行字段多列时对值字段进行排序

=GROUPBY(B2:C15,D2:D15,SUM,,,-3)

当第6个参数设置-3对第3列值字段进行降序排序时,可以发现,排序结果似乎和我们想象的不太一样,1月C产品合计261最多却没有排到第1位,这是因为我们省略了第8个参数,第8个参数字段关系是控制排序时的模式,当参数省略时,默认值是层级模式,在层级模式下排序函数会先根据行字段的首列小计排序,然后再对每组排序(层级模式下即使不显示小计也按此逻辑排序)

=GROUPBY(B2:C15,D2:D15,SUM,,2,-3)

第5个参数设置2显示小计,可以更直观的看到排序逻辑。

现在我们需要直接按汇总后的数量降序排序,可以将函数第8个参数字段关系排序模式设置1表格模式即可。

=GROUPBY(B2:C15,D2:D15,SUM,,,-3,,1)

当参数省略时,汇总结果为升序排序。

四、汇总后按原表数据顺序排序

4.1、按原表数据顺序排序(有序号列)

=GROUPBY(B2:B15,HSTACK(C2:C15,A2:A15),HSTACK(SUM,MIN),,,3)

如果原表有序号列,可以使用HSTACK函数将值字段列与序号列拼接,对序号列指定MIN或MAX函数,然后根据汇总后的列数设置第6个参数升序排序即可。

=DROP(GROUPBY(B2:B15,HSTACK(C2:C15,A2:A15),HSTACK(SUM,MIN),,,3),1,-1)

使用DROP函数将第1行标题,最一列辅助列删除即可。

4.2、按原表数据顺序排序(无序号列)

=DROP(GROUPBY(A2:A15,HSTACK(B2:B15,SEQUENCE(ROWS(A2:A15))),HSTACK(SUM,MIN),,,3),1,-1)

如果原表没有序号列可以使用"SEQUENCE(ROWS(A2:A15))"公式生成序号。

五、筛选

5.1、根据月份和产品汇总完成数量

=GROUPBY(B2:C15,D2:D15,SUM,,,-3,E2:E15="完成",1)

函数第7个参数可以添加筛选条件,对满足条件的行进行汇总。

六、自定义函数

6.1、根据星期汇总姓名

=GROUPBY(A1:A15,B1:B15,ARRAYTOTEXT,3,0)

GROUPBY函数在分组汇总除了可以对数值进行汇总计算,还可以对文本字符串进行拼接,ARRAYTOTEXT函数可以使用(逗号和空格)作为分隔符将多个字符串拼接,如果需要其他分隔符号,可以使用TEXTJOIN函数。

=GROUPBY(A1:A15,B1:B15,LAMBDA(x,TEXTJOIN("、",TRUE,x)),3,0)

可以使用LET函数创建一个自定义函数,然后在GROUPBY中使用创建的自定义函数。

6.2、根据时间计算每小时的最小值、最大值和差值(极差)

七、合并单元格汇总

7.1、根据日期和姓名汇总金额

=LET(fx,LAMBDA(a,SCAN(,a,LAMBDA(x,y,IF(y<>"",y,x)))),GROUPBY(HSTACK(fx(A1:A21),B1:B21),C1:C21,SUM,3))

使用LET函数创建一个名称为fx的自定义函数,功能是拆分填充合并单元格

LAMBDA(a,SCAN(,a,LAMBDA(x,y,IF(y<>"",y,x))))

在GROUPBY函数中调用fx自定义函数将合并单元格拆分填充后,使用HSTACK函数将姓名拼接作为GROUPBY函数第一个参数即可。

如果需要根据姓名和日期汇总金额,使用HSTACK拼接时将姓名放前面即可。

=LET(fx,LAMBDA(a,SCAN(,a,LAMBDA(x,y,IF(y<>"",y,x)))),GROUPBY(HSTACK(B1:B21,fx(A1:A21)),C1:C21,SUM,3))

八、二维转一维

8.1、转换多列单行表头

=GROUPBY(A2:B7,C2:F7,CHOOSE({1,2},SINGLE,TOCOL(C1:F1)),,0)

使用CHOOSE函数构建纵向计算数组,使用SINGLE函数返回聚合后的首值,使用TOCOL函数将标题行转换为一列,即可实现二维结构的数据转一维。

8.2、转换多列多行表头

=LET(fx,LAMBDA(a,SCAN(,a,LAMBDA(x,y,IF(y<>"",y,x)))),GROUPBY(A3:B7,C3:H7,CHOOSE({1,2,3},SINGLE,TOCOL(fx(C1:H1)),TOCOL(C2:H2)),,0))

当需要转换多列标题时,使用CHOOSE函数构建多列数组,依次传入标题行,如果标题行有合并单元格,可调用拆分合并单元格的自定义函数,拆分后传入,即可实现将多行表头的二维结构的数据转一维。

PIVOTBY函数

函数语法

一、基础用法

1.1、根据月份、姓名汇总数量

=PIVOTBY(C2:C17,B2:B17,D2:D17,SUM)

1.2、根据日期汇总姓名

=PIVOTBY(B2:B21,"姓名"&SCAN
(0,B2:B21,LAMBDA(x,y,IF(y=OFFSET(y,-1,),x+1,1))),C2:C21,CONCAT,0,0,,0)

使用SCAN函数根据日期添加序号,然后将添加的序列作为列字段参数即可。

如果数据源日期不是顺序排序,可以使用MAP、COUNTIF函数添加序号。

=PIVOTBY(B2:B21,"姓名"&
MAP(B2:B21,LAMBDA(x,COUNTIF(A2:x,x))),C2:C21,CONCAT,0,0,,0)

注:虽然使用MAP、COUNTIF函数公式更短一些,但是由于COUNTIF函数计算效率很低,当数据过万行时,建议将数据源排序后使用SCAN函数添加序号。

1.3、根据星期汇总姓名(按原表数据顺序排序)

=PIVOTBY(B2:B21,"姓名"&SCAN(0,B2:B21,LAMBDA(x,y,IF(y=OFFSET(y,-1,),x+1,1))),C2:C21,CONCAT,0,0,,0)

当前汇总结果的顺序是根据行字段升序排序,如果需要按原表数据顺序排序,有两种方法。

方法1

使用MATCH函数计算行字段每个值的位置,然后使用HSTACK函数将要汇总的行字段位置和要汇总的行字段拼接,PIVOTBY函数返回结果后使用DROP函数删除第1列即可。

方法2

使用LET函数将PIVOTBY函数返回结果指定名称x,然后使用SORTBY函数对PIVOTBY函数返回的结果排序。

1.4、根据姓名、月份对汇总数值(横向汇总)

=LET(fx,LAMBDA(x,TOCOL(IF(C2:K7<>"",x,NA()),3)),PIVOTBY(fx(B2:B7),fx(MONTH(C1:K1)),fx(C2:K7),SUM))

使用LET、LAMBDA函数创建将数据转为一列的自定义函数,依次调用自定义函数将姓名、日期和数值转为一列后,作为PIVOTBY函数的前3个参数即可。

计算效率提升

GROUPBY和PIVOTBY函数极大地简化了分组统计的操作流程,同时在数据处理效率上实现了显著的飞跃。与MSO相比,当面对大量数据时,WPS所展现出的效率优势更加突出,计算时间对比如下图所示。

在实际工作中,当需要计算大量数据时(上万行数据),SUMIFS、COUNTIFS、MINIFS、MAXIFS、AVERAGEIFS等函数计算效率很慢,使用GROUPBY函数可以解决这一问题。

GROUPBY函数返回的结果默认对行字段进行升级排序,在使用XLOOKUP函数匹配时,XLOOKUP函数第6个参数搜索模式设置2,二分搜索(升序排序),当数据量较大时,计算效率可以提升上百倍。

1.1、SUMIFS和GROUPBY函数计算时间对比

SUMIFS公式

=SUMIFS(B:B,A:A,A2)

GROUPBY和XLOOKUP公式

=GROUPBY(A2:A200000,B2:B200000,SUM)
=XLOOKUP(A2:A200000,E:E,F:F,,,2)

使用SUMIFS和GROUPBY、XLOOKUP函数分别对100、1000、2000...20000行数据进行测试,计算时间对比如下图所示。

1.2、FILTER和GROUPBY函数计算时间对比

FILTER函数公式

=TEXTJOIN("-",1,FILTER(B$2:B$100001,A$2:A$100001=A2))

GROUPBY和XLOOKUP公式

=GROUPBY(A2:A100001,B2:B100001,LAMBDA(x,TEXTJOIN("-",1,x)))
=XLOOKUP(A2:A100001,E:E,F:F,,,2)

使用FILTER和GROUPBY、XLOOKUP函数分别对1000、5000、10000...100000行数据进行测试,计算时间对比如下图所示。

8月版本18166已开始灰度更新,已经更新到此版本的小伙伴可以开始使用新GROUPBY、PIVOTBY函数了。

目前WPS32位18166版本官网还没有更新,想提前体验新函数的小伙伴可以点下方链接下载

本文示例文件下载地址

- - - END - - -

辽宁省
浏览 3391
28
29
分享
29 +1
25
28 +1
全部评论 25
 
点赞收藏学习!
· 辽宁省
1
回复
非常实用!
· 辽宁省
1
回复
 
引用: 当需要计算的行字段或值字段的多列单元格区域或多列数组不是连续的时,可以使用HSATCK函数拼接,或使用CHOOSECOLS函数返回指定列。 ===== 实际上,行字段目前还不支持hstack,并且行字段并不能自由选择。
· 河北省
回复
 
收藏学习
· 辽宁省
回复
 
您好,我对这个公式GROUPBY(A2:B7,C2:F7,CHOOSE({1,2},SINGLE,TOCOL(C1:F1)),,0)中的第三个参数不太理解,(1)SINGLE这个函数的功能是什么(2)在WPS中没有单独找到这个函数(3)月份在数量的前面,取得这种效果的原理是什么呢? 麻烦老师有空的时候麻烦帮解惑
· 山西省
回复
 
用GROUPBY能否统计出如SUMIF符合条件一部分合计数?
· 广西
回复
可以利用筛选这个参数。
· 河北省
回复
 
高效率
· 重庆
回复
 
这个公式在Wps中不能运行,而在exce中可以运行=GROUPBY(财政!A1:E29,财政!F1:X29,IF({1,0},SUM,TOCOL(财政!F1:X1)),3,0),其实就相当于逆透视功能吧!
· 江西省
回复
 
实测17827版本的智能表格实际就已经可以使用这个函数了,但是普通表格不行,还是建议等官方更新吧
· 浙江省
回复
 
NP
· 东京都
回复
 
迫不及待,官网什么时候能下载?
· 云南省
回复
 
又多了一种迭代方法,按“分组”迭代。
· 云南省
回复
 
SINGLE() 这个函数也会一并发出吗?
· 云南省
回复
 
点赞收藏
· 广东省
回复
 
清华学弟任泽岩

创作者俱乐部成员

快快置顶!!!!!!
· 辽宁省
回复
 
谢谢大佬
· 广东省
回复
 
马成功老师

创作者俱乐部成员

感谢科普这么多的内容。辛苦了
· 北京
回复
 
Tam Kingsley

创作者俱乐部成员

groupby函数的第一参数行字段为三列或以上时,实现自定义排序先后顺序?例如假设行字段为三列的情况,我先按第三列排,再按第二列排,最后再按第一列排序,这样可以吗?或者可能怎么实现?
· 广东省
回复
 
懒得批爆

创作者俱乐部成员

额,感觉参数比我的源数据维度还多,确实找不到应用场景
· 四川省
1
回复
可以理解为数据透视表的函数化
· 湖北省
回复
 
wps新路

WPS函数专家

跟着飞鱼哥学习
· 重庆
1
回复
 
收藏
· 山东省
回复