罗兰在MATLAB的艺术

把想法变成MATLAB

请注意

罗兰在MATLAB的艺术已经存档,不会被更新。

组数据表上执行计算的方法

今天我想介绍一个客座博客,斯蒂芬•多伊工作的团队在MathWorks MATLAB文档。斯蒂芬•将讨论不同的方法对数据进行分组和对这些群体进行计算,使用

内容

创建表

表方便用于数据的容器。表中的变量可以具有不同的数据类型,但是必须有相同数量的行。您可以访问表数据行,通过变量或变量名。和您可以指定组内表变量,在这些组织执行计算。今天我将显示几种不同的方式将函数应用到组织表。

首先,让我们创建一个表。您可以创建一个表使用函数,导入工具,或者是readtable函数。我要用readtable读取数据从一个附带的示例文件MATLAB。该文件outages.csv包含电力中断的模拟数据在一段12年在美国。读表。显示前五行,用表索引。

T = readtable (“outages.csv”,“格式”,' % C % D % f % f % D % C ');:T (1:5)
ans = 5×6表地区OutageTime损失客户RestorationTime引起_____ ___________ ______ __________ ___________售予西南2002-02-01 12:18 458.98 - 1.8202 e + 06 2002-02-01 16:50暴风雪东南2003-01-23 00:49 530.14 - 2.1204 e + 05 NaT暴风雪东南2003-02-07)21:15 289.4 - 1.4294 e + 05 2003-02-07 08:14暴风雪西2004-04-06 05:44 434.81 - 3.4037 e + 05 2004-04-06 06:10设备故障中西部2002-03-16 06:18 186.44 - 2.1275 e + 05 2002-03-16 23:23严重的风暴

有六个文件中的列。因为我希望指定表的数据类型的变量,我使用了格式名称-值对的论点。T有两个分类变量(指定% C),两个datetime变量(% D)和两个数值变量(% f)。

对每个数字变量进行计算

一旦数据表中,你可以在不同的表执行计算变量。一种方法是使用点符号引用表变量的名字和执行计算。例如,计算客户的数量受停电影响使用总和功能,省略任何可能的值T.Customers

totalCustomers =总和(T.Customers,“omitnan”)
totalCustomers = 1.903 e + 08年

您还可以将一个函数应用到每个表变量,使用varfun函数。varfun是特别有用的应用一个函数并返回另一个表中的结果。

然而,您可能想要一个函数只适用于某一特定类型的变量。你可以指定类型的变量vartype函数。在这里我要下标T数值变量,计算每一个的意思。因为有一些的变量值,我将包装的意思是在一个匿名函数,所以我可以使用“omitnan”国旗。

T2 = T (:, vartype (“数字”));omean = @ (x)的意思是(x,“omitnan”);意味着= varfun (omean, T2)
意味着= 1×2表Fun_Loss Fun_Customers ________ _________________ 563.89 - 1.6693 e + 05

在组织执行计算数值变量

一个更有趣的表组织数据,并开始寻找组之间的差异。例如,之间的平均功率损失的区别是什么东北和西南地区吗?

要回答这个问题,您可以通过指定一个或多个表变量分组变量。分组变量定义组,你把其他表变量。然后您可以应用一个函数内每组每个表变量和结果。关于分组变量,看看将数据分组变量

您可以使用与分组变量varfun我上面描述的函数。指定地区这个表中作为分组变量。这是类别变量,特别是方便利用作为分组变量。指定损失客户作为输入变量,并计算平均值的地区为这两个变量。我将使用相同的omean我上面指定的函数。

meanByRegion = varfun (omean T“GroupingVariables”,“地区”,“数据源”,{“损失”,“客户”})
meanByRegion = 5×4表地区GroupCount Fun_Loss Fun_Customers _____ __________ ________ _________________中西部142 1137.7 - 2.4015 e + 05年东北557 551.65 - 1.4917 e + 05年东南389 495.35 - 1.6776 e + 05年西南26日493.88 - 2.6975 e + 05西354 433.37 - 1.5201 e + 05

另一种方法应用分组变量数据表中的变量是使用accumarray函数。如果我把T.Region数字数组,和提取T.LossT,那么我可以计算平均功率损失/地区使用accumarray,就像我一样varfun

区域=双(T.Region);= accumarray([],地区,T.Loss omean)
= 1137.7 551.65 495.35 493.88 433.37

accumarray操作数组。所以使用accumarray桌子上的变量,你必须从表中提取它。分组变量必须是一个数字,输出参数是一个数组,而不是一个表。虽然您可以使用accumarray表变量,它缺乏很多的便利varfun提供了。

您可以指定多个分组变量使用varfun。例如,我会指定地区导致作为分组变量。组被定义为组合的区域和原因。

meanByRegionAndCause = varfun (omean T“GroupingVariables”,{“地区”,“原因”},“数据源”,{“损失”,“客户”});:meanByRegionAndCause (1:5)
ans = 5×5表区域造成GroupCount Fun_Loss Fun_Customers ___________ _____ ________ _________________中西部攻击12 0 0中西部能源应急19 343.37 536.09 57603中西部设备故障9 29704中西部暴风31日1055.7 - 4.3584 e + 05中西部雷雨32 941.07 - 1.3301 e + 05

多个变量作为函数的输入参数

另一个简单的计算是通过区域平均停电持续时间。这个计算的基础是之间的差异OutageTimeRestorationTime表变量。

你可能会认为使用varfun这个计算。困难在于varfun单独一个函数适用于每个表变量。但是这个计算需要两个变量。换句话说,我们想应用一个函数需要两个输入参数。

解决方案是使用rowfun函数。与rowfun,所有的表变量作为输入参数。如果表有N函数变量,那么你必须接受申请N输入参数。

执行此计算,我将首先定义一个匿名函数,减去一个输入参数,然后计算平均值。然后我会计算平均停电持续时间的地区使用rowfun

meanDiff = @ (a, b)的意思是(abs (a - b),“omitnan”);meanOutageTimes = rowfun (meanDiff T“GroupingVariables”,“地区”,“数据源”,{“OutageTime”,“RestorationTime”})
meanOutageTimes = 5×3表地区GroupCount Var3 _____ _____ _____中西部东北142 819:14:44东南557 581:02:18西南389 40:49:49 26 59:31:07西354 673:27:12

请注意,OutageTimeRestorationTimedatetime变量。您可以执行算术和datetime变量,就可以用数值变量。

重命名一个变量,您可以访问VariableNames表的属性和改变它的名字。表包含元数据,比如变量名称和描述,称为属性属性

meanOutageTimes.Properties.VariableNames {“Var3”}=“mean_OutageTime”;:meanOutageTimes (1:5)
ans = 5×3表地区GroupCount mean_OutageTime _____ __________售予中西部东北142 819:14:44东南557 581:02:18西南389 40:49:49 26 59:31:07西354 673:27:12

使用组在多个计算和汇总结果

varfunrowfun是适合当您想要执行相同的计算表变量。但如果你要计算不同数量吗?例如,您可能想要计算平均功率损失,而且还最低停电期间,由区域。在这种情况下,您可以执行计算和汇总结果使用findgroupssplitapply功能。

这些函数的工作有所不同varfunrowfun。的findgroups函数返回数值指标,对应于您所指定的分组变量。作为第二输出,它还返回一个表的组。然后你可以叫splitapply一个函数应用于每组内的变量。

例如,我将计算平均功率损失,最小的停机时间,和客户的最大数量影响,地区。我将指定组使用一次findgroups。然后我可以使用组织多个调用splitapply

我还要换齿轮,通过删除所有行或缺失值。我将使用rmmissing函数来删除这些行,所以我不需要指定“omitnan”国旗在每个函数调用。

T = rmmissing (T);(G,结果)= findgroups (T (:,“地区”));meanLoss = splitapply (@mean, T.Loss, G);minOutageTime = splitapply (@min, T。RestorationTime- T.OutageTime,G); maxCustomers = splitapply(@max,T.Customers,G)
maxCustomers = 3.295 2.2249 5.9689 e + e + 06 06 e + 06年1.8202 4.26 e + e + 06 06

的输出splitapply是一个数组。maxCustomers是一个5-by-1数字数组。然而,您可以汇总结果通过将它们作为变量添加到表中结果,第二个输出findgroups

结果。meanLoss= meanLoss; results.minOutageTime = minOutageTime; results.maxCustomers = maxCustomers
结果= 5×4表地区meanLoss minOutageTime maxCustomers _____ ________ _________________ _______中西部907.19就是3.295 e + 06东北383.86就是5.9689 e + 06东南508.34就是2.2249西南541.66 00:28:00 1.8202 e + e + 06 06西429.73就是4.26 e + 06

高桌子上执行计算

到目前为止,我曾与一个表,小到可以装到内存中。但如果有太多的数据,它不会适合所有内存吗?我可能还想把它当作一个表和使用相同的功能。

这可以很容易地通过创建一个高表。一系列高表是一种高在MATLAB。高的数组和高表知道如何读取数据在一块,你想要执行计算,然后收集最后的输出。使用高表的语法非常类似于使用一个表。

高的数组和高表上的更多信息,参见高大的数组

这是如何工作的,我将创建一个表的高outages.csv。当然这有点愚蠢的创建一个高表的文件适合在内存中,但这说明了如何使用一个更大的表。

而不是打电话readtable,我将开始通过调用数据存储阅读outages.csv到一个数据存储。

然后我会打电话给ds,创建一个高表的数据存储。现在我有一个高表看起来和我工作的桌子很像在前面的部分。你看到不同的一点是,高表显示为一个M-by-6表,显示的行数不清楚。

ds =数据存储(“outages.csv”);T =高(ds)
开始平行池(parpool)使用“本地”概要文件…连接到两个工人。T =米×6表地区OutageTime损失客户RestorationTime引起___________ ___________ ______ __________ ___________ _________________,“西南”2002-02-01 12:18 458.98 - 1.8202 e + 06 2002-02-01 16:50“暴风雪”“东南”2003-01-23 00:49 530.14 - 2.1204 e + 05 NaT“暴风雪”“东南”2003-02-07)21:15 289.4 - 1.4294 e + 05 2003-02-07 08:14“暴风雪”“西方”2004-04-06 05:44 434.81 - 3.4037 e + 05 2004-04-06 06:10“设备故障”“中西部”2002-03-16 06:18 186.44 - 2.1275 e + 05 2002-03-16 23:23“暴风”“西方”2003-06-18 02:49 0 0 2003-06-18 10:54‘攻击’‘西方’2004-06-20 39 231.29南2004-06-20 19:16“设备故障”“西方”2002-06-06 19:28 311.86南2002-06-06 00:51“设备故障”::::::::::::

现在我可以使用findgroupssplitapply执行一些相同的计算。我又一次将的意思是在一个匿名函数,所以我可以忽略值,像我一样。

omean = @ (x)的意思是(x,“omitnan”);T.Region= categorical(T.Region); T.Cause = categorical(T.Cause); G = findgroups(T.Region); meanLoss = splitapply(omean,T.Loss,G); meanCustomers = splitapply(omean,T.Customers,G)
双列向量meanCustomers = M×1高?吗?吗?::

而不是看到输出,我们看到一串问号。这是什么意思?只是,我还没有执行任何计算。在这一点上,我只定义了计算我想在高台上执行。不执行,直到我的计算收集结果,通过调用收集函数。的输出收集不是一个高大的数组和必须适合到内存中。

meanLoss =收集(meanLoss);meanCustomers =收集(meanCustomers)
评估高表达式使用并行池“当地”:4 -通过1:完成4秒4 -通过2:完成2秒-通过3 4:完成2秒-通过4 4:在2秒完成评估在25秒完成评估高表达式使用并行池“当地”:通过1对1:在2秒完成评估在5秒完成meanCustomers = 2.4015 e + 05年1.4917 1.6776 e + e + 05年05年2.6975 e + e + 05年05年1.5201

现在让我们汇总结果表中。自meanLossmeanCustomers不高的数组,结果不是一个高的表。添加区域作为另一个表变量。

= =结果表(meanLoss meanCustomers)地区独特的(T.Region);结果。地区=收集(地区)
结果= 5×2表meanLoss meanCustomers ________ _________________ 1137.7 - 2.4015 e + 05年551.65 1.4917 e + 05年495.35 - 1.6776 e + 05年493.88 - 2.6975 e + 05年433.37 1.5201 e + 05评估高表达式使用并行池“当地”:通过1对1:在1秒完成评估完成在2秒结果= 5×3表meanLoss meanCustomers中西部地区________ _________________ _____ 1137.7 - 2.4015 e + 05年551.65 - 1.4917 e + 05东北495.35 - 1.6776 e + 05东南西南433.37 - 1.5201 493.88 - 2.6975 e + 05 e + 05年西方

把对你的表

我已经向您展示了几种方法你可以组数据表进行计算。总而言之,您可以使用一个或多个分组变量来指定组中的其他表变量。然后您可以应用功能组表中的变量。

应用:

  • 单个表变量和函数返回一个数组,使用accumarray
  • 相同的函数变量和返回一个表,每个表使用varfun
  • 一个函数,它要求所有表变量作为输入参数,并返回一个表,使用rowfun
  • 不同的功能,不同的结果,表变量和建立一个表使用findgroupssplitapply

你呢?做了分析表在哪里accumarray,varfun,rowfun,findgroupssplitapply可能会有帮助吗?你有情况需要高表吗?让我们知道在这里




发表与MATLAB®R2017a


评论

留下你的评论,请点击在这里MathWorks账户登录或创建一个新的。