Main Content

表数据计算

此示例说明如何对表中的数据执行计算。表可以包含同时数值和非数值数据。确定包含数值数据的表变量后,您可以使用花括号或圆点表示法来访问这些变量中的数据。然后,您可以对数值数据执行算术运算或调用函数,并将结果赋回表中,所有这些都在一行代码中完成。您还可以使用 rowfun 函数对表行执行计算,使用 varfun 函数对变量执行计算。如果表中有数据组,可以使用 groupsummaryrowfunvarfun 函数对表中的每组数据执行计算。

将样本数据读入到表中

使用 readtable 函数将 CSV(逗号分隔值)文件 testScores.csv 中的数据读入表中。该示例文件包含就读于两所不同学校的 10 名学生的考试成绩。输出表包含具有数值数据的变量和具有文本数据的其他变量。其中一个变量 School 有一组固定的值或类别。这些类别表示此表中的两组学生。将 School 转换为一个 categorical 变量。

scores = readtable("testScores.csv","TextType","string");
scores.School = categorical(scores.School)
scores=10×5 table
     LastName       School      Test1    Test2    Test3
    __________    __________    _____    _____    _____

    "Jeong"       XYZ School     90       87       93  
    "Collins"     XYZ School     87       85       83  
    "Torres"      XYZ School     86       85       88  
    "Phillips"    ABC School     75       80       72  
    "Ling"        ABC School     89       86       87  
    "Ramirez"     ABC School     96       92       98  
    "Lee"         XYZ School     78       75       77  
    "Walker"      ABC School     91       94       92  
    "Garcia"      ABC School     86       83       85  
    "Chang"       XYZ School     79       76       82  

创建包含数值数据的子表

创建一个只有数值数据的子表。由于前两个变量包含非数值数据,因此一个简单的方法是指定其他变量来对表进行索引。

numericScores = scores(:,3:end)
numericScores=10×3 table
    Test1    Test2    Test3
    _____    _____    _____

     90       87       93  
     87       85       83  
     86       85       88  
     75       80       72  
     89       86       87  
     96       92       98  
     78       75       77  
     91       94       92  
     86       83       85  
     79       76       82  

您也可以使用 vartype 函数按数据类型指定变量。如果一个大型表包含具有不同数据类型的许多变量,则此函数非常有用。它返回可用于指定表变量的下标。

numericVars = vartype("numeric")
numericVars = 
	table vartype subscript:

		Select table variables matching the type 'numeric'

	See Access Data in a Table.

numericScores = scores(:,numericVars)
numericScores=10×3 table
    Test1    Test2    Test3
    _____    _____    _____

     90       87       93  
     87       85       83  
     86       85       88  
     75       80       72  
     89       86       87  
     96       92       98  
     78       75       77  
     91       94       92  
     86       83       85  
     79       76       82  

对表数据执行算术运算和调用函数

考试分数为百分制。要将分数转换为另一不同的分数制,请将分数乘以相同的系数。

但是,无法使用与处理数值数组相同的语法。在这种情况下,请将数据提取到一个数组中,对其进行缩放,然后将其赋回该表中。这样,您可以在一行代码中对内容执行算术运算或调用函数。

要提取表的内容,请使用花括号。例如,以下语法指定 numericScores 的所有行和所有表变量,并以数值矩阵形式返回结果。只要表变量具有兼容的数据类型,就可以用这种方式串联其内容。

A = numericScores{:,:}
A = 10×3

    90    87    93
    87    85    83
    86    85    88
    75    80    72
    89    86    87
    96    92    98
    78    75    77
    91    94    92
    86    83    85
    79    76    82

如果矩阵的大小与表的大小相同,并且具有兼容的数据类型,则可以将矩阵赋给表的内容。

缩放数值数据,使考试分数采用 25 分制,并将其赋回表中。

numericScores{:,:} = numericScores{:,:} * 0.25
numericScores=10×3 table
    Test1    Test2    Test3
    _____    _____    _____

     22.5    21.75    23.25
    21.75    21.25    20.75
     21.5    21.25       22
    18.75       20       18
    22.25     21.5    21.75
       24       23     24.5
     19.5    18.75    19.25
    22.75     23.5       23
     21.5    20.75    21.25
    19.75       19     20.5

您可以使用 T.Variables 替代花括号来指定所有表变量。T.VariablesT{:,:} 语法表示相同的内容。

例如,从每个表变量中减去该变量的最小值。

numericScores.Variables = numericScores.Variables - min(numericScores.Variables)
numericScores=10×3 table
    Test1    Test2    Test3
    _____    _____    _____

    3.75        3     5.25 
       3      2.5     2.75 
    2.75      2.5        4 
       0     1.25        0 
     3.5     2.75     3.75 
    5.25     4.25      6.5 
    0.75        0     1.25 
       4     4.75        5 
    2.75        2     3.25 
       1     0.25      2.5 

通过使用圆点表示法和变量名称,可以一次对一个变量执行计算。例如,对 Test3 中的最后一组分数加五分予以修正。其他表变量不受此操作的影响。

numericScores.Test3 = numericScores.Test3 + 5
numericScores=10×3 table
    Test1    Test2    Test3
    _____    _____    _____

    3.75        3     10.25
       3      2.5      7.75
    2.75      2.5         9
       0     1.25         5
     3.5     2.75      8.75
    5.25     4.25      11.5
    0.75        0      6.25
       4     4.75        10
    2.75        2      8.25
       1     0.25       7.5

对每个表行进行计算

找出每个学生考试分数的均值、最小值和最大值。计算每行的这些值。将它们作为新的表变量赋给原始表。

一种简单而有用的方法是将数据提取到一个矩阵中,对该矩阵调用一个函数,然后将输出赋给一个新的表变量。例如,计算每行的平均考试分数。然后将它们添加到新的表变量 TestMean 中的 scores。使用花括号将 Test1Test2Test3 中的数值数据提取到一个矩阵中。要计算行的均值,请在调用 mean 时将维度指定为 2

vars = ["Test1","Test2","Test3"];
scores.TestMean = mean(scores{:,vars},2)
scores=10×6 table
     LastName       School      Test1    Test2    Test3    TestMean
    __________    __________    _____    _____    _____    ________

    "Jeong"       XYZ School     90       87       93           90 
    "Collins"     XYZ School     87       85       83           85 
    "Torres"      XYZ School     86       85       88       86.333 
    "Phillips"    ABC School     75       80       72       75.667 
    "Ling"        ABC School     89       86       87       87.333 
    "Ramirez"     ABC School     96       92       98       95.333 
    "Lee"         XYZ School     78       75       77       76.667 
    "Walker"      ABC School     91       94       92       92.333 
    "Garcia"      ABC School     86       83       85       84.667 
    "Chang"       XYZ School     79       76       82           79 

另一种对行执行计算的方法是使用 rowfun 函数。使用 rowfun 时,不需要从表中提取数据。而要将表和要应用于数据的函数作为输入参数传递给 rowfun。虽然语法有点复数,但当您应用的函数接受多个输入参数或返回多个输出参数时,rowfun 会很有用。

例如,使用 bounds 函数查找最低和最高考试分数。bounds 函数返回两个输出参数,因此通过使用 rowfun 将其应用于 scoresrowfun 的输出是包含 TestMinTestMax 变量的一个新表。在本例中,还要将 "SeparateInputs" 指定为 false,从而将每行的值先合并为一个向量,然后再传递给 bounds

minmaxTest = rowfun(@bounds, ...
                    scores, ...
                    "InputVariables",vars, ...
                    "OutputVariableNames",["TestMin","TestMax"], ...
                    "SeparateInputs",false)
minmaxTest=10×2 table
    TestMin    TestMax
    _______    _______

      87         93   
      83         87   
      85         88   
      72         80   
      86         89   
      92         98   
      75         78   
      91         94   
      83         86   
      76         82   

串联 scoresminmaxTest 以将这些值置于一个表中。

scores = [scores minmaxTest]
scores=10×8 table
     LastName       School      Test1    Test2    Test3    TestMean    TestMin    TestMax
    __________    __________    _____    _____    _____    ________    _______    _______

    "Jeong"       XYZ School     90       87       93           90       87         93   
    "Collins"     XYZ School     87       85       83           85       83         87   
    "Torres"      XYZ School     86       85       88       86.333       85         88   
    "Phillips"    ABC School     75       80       72       75.667       72         80   
    "Ling"        ABC School     89       86       87       87.333       86         89   
    "Ramirez"     ABC School     96       92       98       95.333       92         98   
    "Lee"         XYZ School     78       75       77       76.667       75         78   
    "Walker"      ABC School     91       94       92       92.333       91         94   
    "Garcia"      ABC School     86       83       85       84.667       83         86   
    "Chang"       XYZ School     79       76       82           79       76         82   

对每个表变量进行计算

求每次考试的均值分数。对表变量计算这些值。

最简单的方法是使用 mean。首先使用花括号将 Test1Test2Test3 中的数值数据提取到一个矩阵中。然后调用 mean 计算该矩阵每列的均值。输出是一个数值向量,其中每个元素是一个表变量的均值。

vars = ["Test1","Test2","Test3"];
meanOfEachTest = mean(scores{:,vars})
meanOfEachTest = 1×3

   85.7000   84.3000   85.7000

对表变量执行计算的另一种方法是使用 varfun 函数。使用 varfun 时,不需要从表中提取数据。而要将表和要应用于数据的函数作为输入参数传递给 varfun

使用 varfun 计算均值分数。输出是一个新表,其中包含表变量的有意义名称。

meanOfEachTest = varfun(@mean, ...
                        scores, ...
                        "InputVariables",vars)
meanOfEachTest=1×3 table
    mean_Test1    mean_Test2    mean_Test3
    __________    __________    __________

       85.7          84.3          85.7   

使用表中的数据组进行计算

如果您的表有一个或多个分组变量,则您可以对表中的数据组执行计算。您可以使用一个分组变量中的值来指定各行所属的组。

例如,scores 中的 School 变量有两个值,即 ABC SchoolXYZ School。您可以将这两个值视为表示 scores 中数据组的类别。在本例中,可以按学校执行计算。

要应用函数并使用分组变量,可以使用 varfun 函数。您可以指定函数,如 mean,然后使用 varfun 将其应用于您指定的每个表变量。当您还指定了分组变量时,varfun 会将该函数应用于每个表变量中的每个组。

按学校计算每次考试的分数均值。

vars = ["Test1","Test2","Test3"];
meanScoresBySchool = varfun(@mean, ...
                            scores, ...
                            "InputVariables",vars, ...
                            "GroupingVariables","School")
meanScoresBySchool=2×5 table
      School      GroupCount    mean_Test1    mean_Test2    mean_Test3
    __________    __________    __________    __________    __________

    ABC School        5            87.4            87          86.8   
    XYZ School        5              84          81.6          84.6   

从 R2018a 开始,您还可以使用 groupsummary 函数对每个表变量中的数据组执行计算。

meanScoresBySchool = groupsummary(scores,"School","mean",vars)
meanScoresBySchool=2×5 table
      School      GroupCount    mean_Test1    mean_Test2    mean_Test3
    __________    __________    __________    __________    __________

    ABC School        5            87.4            87          86.8   
    XYZ School        5              84          81.6          84.6   

groupsummary 的语法稍微简单一些。此外,您可以使用 groupsummary 一次指定多个方法。例如,按学校找出每次考试的最低分和最高分。

minmaxBySchool = groupsummary(scores,"School",["min","max"],vars)
minmaxBySchool=2×8 table
      School      GroupCount    min_Test1    max_Test1    min_Test2    max_Test2    min_Test3    max_Test3
    __________    __________    _________    _________    _________    _________    _________    _________

    ABC School        5            75           96           80           94           72           98    
    XYZ School        5            78           90           75           87           77           93    

要使用 groupsummary 的所有预定义方法,请指定 "all" 作为方法。按学校计算关于均值考试分数的所有统计量。

allStatsBySchool = groupsummary(scores,"School","all","TestMean")
allStatsBySchool=2×13 table
      School      GroupCount    mean_TestMean    sum_TestMean    min_TestMean    max_TestMean    range_TestMean    median_TestMean    mode_TestMean    var_TestMean    std_TestMean    nummissing_TestMean    nnz_TestMean
    __________    __________    _____________    ____________    ____________    ____________    ______________    _______________    _____________    ____________    ____________    ___________________    ____________

    ABC School        5            87.067           435.33          75.667          95.333           19.667            87.333            75.667           57.967          7.6136                0                  5      
    XYZ School        5              83.4              417          76.667              90           13.333                85            76.667           29.856           5.464                0                  5      

有时,您可能希望在一个表变量中找到某特定值,然后在另一个表变量中找到对应的值。在这种情况下,使用 rowfun

例如,找出每所学校中考试分数均值最高的学生。本例随附的辅助函数 findNameAtMax 返回最高分和获得该分数的学生的姓名。使用 rowfunfindNameAtMax 应用于每组学生。rowfun 函数适用于这一情形,因为 findNameAtMax 有多个输入参数(姓氏和考试分数),并且还返回多个输出参数。

maxScoresBySchool = rowfun(@findNameAtMax, ...
                           scores, ...
                           "InputVariables",["LastName","TestMean"], ...
                           "GroupingVariables","School", ...
                           "OutputVariableNames",["max_TestMean","LastName"])
maxScoresBySchool=2×4 table
      School      GroupCount    max_TestMean    LastName 
    __________    __________    ____________    _________

    ABC School        5            95.333       "Ramirez"
    XYZ School        5                90       "Jeong"  

辅助函数

function [maxValue,lastName] = findNameAtMax(names,values)
    % Return maximum value and the last name 
    % from the row at which the maximum value occurred
    [maxValue,maxIndex] = max(values);
    lastName = names(maxIndex);
end

另请参阅

| | | | |

相关主题