Excel 中遇到较简单的运算,数据分析师常会用 add-ins 辅助解决。本文考查了一些常见的 add-ins,从部署难度、开发难度、晦涩水平等方面进行深度比照,并着重考查了数据计算能力,esProc 在这些 add-ins 中的体现绝对杰出。点击辅助 Excel 的数据计算 add-ins理解详情。
对于大多数简略运算,Excel都提供了不便的实现伎俩,有时是易用的函数,有时是直观的按钮或菜单。但咱们还是会遇到的一些较简单或非凡的运算,依附Excel自身很难实现。Excel提供了add-in接口,能够通过这个接口执行内部程序,从而借助内部语言或脚本实现这些较简单或非凡的运算,达到辅助Excel的目标。
上面,让咱们深刻理解一些Excel的常见数据计算add-ins,并评估它们的计算能力。
Excel DNA
Excel DNA是晚期呈现的一款Excel add-in,它能够把程序员写好的动静库函数放到Excel里应用,动静库能够应用C#/F#/VB.net等语言等编写。
具体用法上,Excel DNA和其余所有add-ins都相似,首先要编写自定义函数。比方上面C#编写的代码中(引自Excel DNA官网),MyFunction是自定义函数名。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ExcelDna.Integration;
namespace MyLibrary
{
public class Class1
{
\[ExcelFunction(Description="few people use this way!")\]
public static string MyFunction(string name)
{
return "Bonjour" + name;
}
}
}
下面的代码须编译成动静库,之后能力在Excel中应用。
接下来,个别要配置自定义函数和add-in的关系。比方上面的DnaSample.dna文件,表明本add-in的名字是"My name",对应的动静库是Mylibrary.dll(含有多个自定义函数)。
<DnaLibrary Name="My name" RuntimeVersion="v4.0">
<ExternalLibrary Path="Mylibrary.dll" />
</DnaLibary>
最初在Excel中配置该add-in,就能够在单元格中调用MyFunction这个函数了,如下:
应该留神到,上述过程有个编译的动作,因为编译过的程序可间接执行,且与Excel集成严密,因而执行效率十分高。这便带来了Excel DNA最大的长处:顺滑无卡顿。
Excel DNA的其余长处从名字就可以看进去,换句话说,该add-in能够充分利用微软DNA架构提供的便当,比方开发语言、开发工具、Excel集成、联动调试等。
还应该留神到,C#/F#/VB.net等语言的通用性很强,实践上是无所不能的,但官网的代码例子却只是字符串输入,体现不出哪怕丝毫的能力,这到底是为什么呢?
因为实践和理论是有差异的。
C#/F#/VB.net等语言不足结构化计算类库,即便最根本的运算都要硬编码实现,代码因而十分繁琐,并不适宜做简单的数据计算。
除了不适宜数据计算,还应留神到C#/F#/VB.net是编译型语言,而不是解释型语言,这就要求用户必须保护一套编译环境,以备批改算法后编译所用,而微软的编译环境配置较简单,桌面数据分析师不易把握。事实上,C#/F#/VB.net等语言自身的技术门槛就很高,这就导致Excel DNA更适宜业余程序员作为接口应用,并不适宜大多数桌面数据分析师间接应用。
除了Excel DNA,还有其余一些add-ins同样不足结构化计算类库,比方基于JAVA语言的JINX。很容易就能判断出,JINX也不适宜数据计算。事实上,Excel自带的VBA在语言能力上和Excel DNA/JINX相当(都不适宜数据计算),但VBA免集成免编译,比Excel DNA/JINX更有竞争劣势。
Excel JavaScript
不言而喻,无论什么add-ins,至多要比VBA不便好用,才值得咱们学习钻研。微软也发现了这个问题,所以2013年推出了Excel JavaScript,一种比VBA更不便的add-ins专用语言。
Excel JavaScript的用法和其余add-ins相似,这里以及后续都不再赘述。值得强调的是,Excel JavaScript是解释型语言,能够随时批改并立刻执行,而无需编译,这一点和Excel DNA区别较大。既然是解释型语言,个别就会存在卡顿问题,但Excel JavaScript是Excel内置的语言,能够在同一个过程中执行,因而实际效果十分顺滑,执行效率仅次于Excel DNA。
内置于Excel还会的带来其余益处,比方无需下载,可间接开发,这便省去了繁琐的部署过程。再比方Excel JavaScript继承了Excel跨平台的能力,只需编写一次,就能够在单机版、网页版、Mac版上无缝迁徙。另外,Excel JavaScript可间接拜访workbook、sheet、cell等Excel对象,开发效率显著晋升。
等一下,下面说的尽管都是Excel JavaScript的劣势,但如同VBA也具备等同的劣势,所以,说好的“更不便”到底体现在哪里?
比VBA更不便,体现在Excel JavaScript的界面控制能力上。换句话说,Excel JavaScript能够用更简略的语法拜访Excel菜单栏、面板按钮、弹出框,能够在JS文件中间接定义add-ins界面,比VBA不便太多了。
惟一的问题是,界面管制并非数据计算add-ins的重点,不值得咱们关注……
不错,既然讲的是数据计算add-ins,那数据计算能力才是关注重点,而不是界面控制能力。但遗憾的是,JavaScript仍然没有任何结构化计算函数,用于做Excel都难以实现的数据计算也没啥特地的劣势,仅仅是让Excel多了一种不同于VBA的脚本语言而已。
pyxll
显然,只有具备结构化计算类库,才算是合格的数据计算add-ins,比方这里要讲的pyxll。Pyxll是基于Python语言的add-in,而Python领有结构化计算类库Pandas。
既然是合格的数据计算add-in,pyxll实现简略算法时天然无需硬编码,比方对指定区域分组汇总:选中Excel中的一批员工记录,传给自定义函数groupEmp,由pyxll执行分组汇总算法,并返回计算结果,只需编写如下代码:
import pandas as pd
import numpy as np
from pyxll import xl_func
@xl_func("dataframe<index=False, columns=True>")
def groupEmp(df):
df=df.groupby("deptid")\['salary'\].agg(\[len, np.sum, np.mean\]) #外围代码:分组汇总
return df
下面外围代码只有一行,其余代码根本都是定式。能够看到,具备结构化库函数的pyxll,能够用十分简洁的代码实现分组汇总等简略算法。
当然,有时也会遇到较简单或非凡的运算,须要用多个函数组合实现,而不是独自应用排序、过滤之类根本函数。遗憾的是,pyxll实现较简单或非凡的运算时不太不便。
比方规范化数据并分组汇总的例子:针对Excel中的住户户型明细表(A-E列),自定义函数需按STYLE和BEDROOMS分组,统计SQFEET、BATHS、PRICE的平均值,其中PRICE列本来是字符串,需去掉$符号,转为数值再计算。
解决前数据
解决后的数据在新sheet中。
实现上述算法的自定义函数如下(只保留外围代码):
for i in range(1, len(b)):
b\[i\]\[4\] = b\[i\]\[4\].replace(“$”,‘ ‘)
b\[i\]\[4\] = b\[i\]\[4\].replace(“,”,‘ ‘)
for i in range(1, len(b)):
for j in \[1, 2, 3, 4\]:
b\[i\]\[j\] = eval(b\[i\]\[j\])
data = pandas.DataFrame(b\[1:\],columns=b\[0\])
out = data.groupby(\[‘STYLE’,‘BEDROOMS’\]).mean()
return out
分组还是只有一句,但后面的预处理却要6行,有点麻烦。
再比方一行分多行的例子:A列存储ID,B列存储ID对应的列表List,List有多个成员,以空格为分隔符。自定义函数需将List按空格拆分,使每个ID对应一个成员。
解决前的数据
解决后的数据在新sheet中:
实现上述算法的自定义函数如下:
split\_dict = df.set\_index('ID').T.to_dict('list')
split_list = \[\]
for key,value in split_dict.items():
anomalies = value\[0\].split(' ')
key_array = np.tile(key,len(anomalies))
split\_df = pd.DataFrame(np.array(\[key\_array,anomalies\]).T,columns=\['ID','ANOMALIES'\])
split\_list.append(split\_df)
df = pd.concat(split\_list,ignore\_index=True)
return df
能够看到,即便只保留外围运算性能,pyxll的代码依然有点简单。这就是pyxll毛病之一:不善于实现较简单或非凡的运算。
pyxll还有一个毛病:Excel要调用内部解释器来解释Python脚本,因而顿挫感较强烈,会重大影响用户体验。当然,顿挫并非pyxll独有的问题,而是所有内部解释型脚本共通的问题,比方XLwings、Bert和RExcel。其中XLwings与pyxll同样是基于Python的add-ins,优缺点根本一样。Bert和RExcel是基于R的add-ins,R专一于迷信模型算法,其结构化计算类库不够业余,因而这两款add-ins的计算能力还不如pyxll,顿挫感也会更强。
当然,解释型语言也有长处,最大的长处是无需编译即可执行,保护批改都很不便。
esProc
esProc是业余的数据计算引擎,也提供了一个Excel add-in,能够应用esProc的SPL语言编写计算脚本。它与pyxll有很多相似之处,比方两者都有丰盛的结构化计算函数,因而能够轻松实现简略算法,比方对指定区域分组汇总,只需编写脚本groupEmp.dfx:
外围代码只有A2一行,十分简洁。之后就能够在Excel单元格中援用自定义函数groupEmp,形如=dfx("groupEmp",A1:D20)。
其余根本算法也能够轻松实现(只留外围代码):
通过理解之前的add-ins,咱们曾经能够得出结论:是否能不便地实现较简单或非凡的运算,才是判断一款add-in的数据计算能力的真正指标。
esProc可能不便地实现较简单或非凡的运算,这是它比pyxll更有劣势的中央。
比方规范化数据并分组汇总,后面用pyxll时显得很麻烦,但esProc就简略多了:
再比方一行分多行,esProc代码更简略:
再举个逻辑更简单的例子:计算分期贷款明细。Excel单元格记录着贷款信息,包含贷款ID,贷款总额、按月分期数、年利率,示意如下:
自定义函数的目标是计算出各期明细,包含:当期还款额、当期利息、当期本金、残余本金。计算结果在新sheet 中该当如下:
下面的算法用pyxll实现会很麻烦,但esProc就很不便:
看起来esProc的数据计算能力的确很弱小,然而,十分遗憾的是,esProc也是基于内部解释器的add-in,还须要JVM来执行,它同样存在卡顿的问题。
esProc through clipboard
有没有方法既能利用esProc弱小的计算能力,还能顺滑地操作esProc?
用剪贴板代替自定义函数!
比方求各科前3名的学生:A列是学生姓名,B-D列别离是数学、英语、物理问题,需要求出每学科问题前3名的学生,并追加到本科问题之后。
解决前数据
选中这些单元格,先用ctrl+C复制到剪贴板,再在esProc脚本中执行如下代码:
执行上述脚本后,只需在Excel的B11格用ctrl+V,即可将剪切板中的数据复制到B11-D13,达到和自定义函数雷同的成果,如下:
相似的,大多数自定义函数都能够用剪切板简略代替,除非遇到一些非凡状况,比方多片区域参加运算。
应该留神到,上述过程尽管能够达到顺滑操作的目标,也能够利用到esProc弱小的计算能力,但并没有应用add-in协定。事实上,如果违心应用剪切板,就没必要部署简单的add-ins,这对数据分析师来说,难道不是一件减轻负担的坏事吗?
还应该留神到,不仅esProc能够利用剪贴板来解决卡顿的问题,pyxll等add-ins实践上也齐全能够,只有它们在未来的版本中提供相似的函数(从剪切板获取数据并转换成外部的结构化数据类型)。
通过后面的比拟,咱们能够得出这样的论断:晦涩的add-ins计算能力差;计算能力强的add-ins存在卡顿景象。配合剪切板应用esProc能够补救卡顿的毛病,更适宜桌面分析师应用。