第9章 数 据 分 析 由于MATLAB面向矩阵,所以它很容易对数据集合进行统计分析。按规定,数据集存储在面向列的矩阵里。也就是,一个矩阵的每一列代表不同的被测变量,每一行代表各个样本或观察值。例如,让我们假定,一个月31天的三城市每日高温(单位为0C)被记录,并赋给脚本M文件中的变量temps,在精通MATLAB工具箱里取名为mmtemp.m。运行M文件,把变量temps放在MATLAB工作空间里。这样,变量temps包含: ? temps temps = 12 8 18 15 9 22 12 5 19 14 8 23 12 6 22 11 9 19 15 9 15 8 10 20 19 7 18 12 7 18 14 10 19 11 8 17 9 7 23 8 8 19 15 8 18 8 9 20 10 7 17 12 7 22 9 8 19 12 8 21 12 8 20 10 9 17 13 12 18 9 10 20 10 6 22 14 7 21 12 5 22 13 7 18 15 10 23 13 11 24 12 12 22 每一行包含了给定一天的高温;每一列包含不同城市的高温。为了使数据可视,把它绘图: ? d=1:31; % number the days of the month ? plot(d, temps) ? xlabel(' Day of Month '),ylabel(' Celsius ') ? title(' Daily High Temperatures in Three Cities ') (见图9.1)  图9.1 三个城市的每日高温 上面的plot命令也说明了plot命令用法的另一种形式。变量d是一个长度为31的向量,而temps是一个31×3矩阵。给定这些数据,plot命令绘出了temps对每一列d的曲线。绘图在第7和8章进一步讨论。 为了说明MATLAB数据分析的一些功能,根据上面温度数据考虑以下命令。 ? avg_temp=mean(temps) avg_temp = 11.9677 8.2258 19.8710 表明第三个城市有最高平均温度。这里MATLAB分别地找出了各列的平均值。 ? avg_avg=mean(avg_temp) avg_avg = 13.3548 找出了三个城市的总平均温度。当输入到数据分析函数是行或列向量时,MATLAB仅对向量执行运算,返回一个标量。 考虑从各城市的均值求每日偏差的问题。即必须从temps的i列中减去avg_temp(i)。我们不能仅仅用以下的语句 ? temps-avg_temp ??? Error using ==> - Matrix dimensions must agree. 因为这个操作不是一个已定义的数组操作(temps是31×3和avg_temp是1×3)。或许最直接的方法是使用For循环。 for i=1:3 tdev( : , i)=temps( : , i)-avg_temp(i) ; end ? tdev tdev = 0.0323 -0.2258 -1.8710 3.0323 0.7742 2.1290 0.0323 -3.2258 -0.8710 2.0323 -0.2258 3.1290 0.0323 -2.2258 2.1290 -0.9677 0.7742 -0.8710 3.0323 0.7742 -4.8710 -3.9677 1.7742 0.1290 7.0323 -1.2258 -1.8710 0.0323 -1.2258 -1.8710 2.0323 1.7742 -0.8710 -0.9677 -0.2258 -2.8710 -2.9677 -1.2258 3.1290 -3.9677 -0.2258 -0.8710 3.0323 -0.2258 -1.8710 -3.9677 0.7742 0.1290 -1.9677 -1.2258 -2.8710 0.0323 -1.2258 2.1290 -2.9677 -0.2258 -0.8710 0.0323 -0.2258 1.1290 0.0323 -0.2258 0.1290 -1.9677 0.7742 -2.8710 1.0323 3.7742 -1.8710 -2.9677 1.7742 0.1290 -1.9677 -2.2258 2.1290 2.0323 -1.2258 1.1290 0.0323 -3.2258 2.1290 1.0323 -1.2258 -1.8710 3.0323 1.7742 3.1290 1.0323 2.7742 4.1290 0.0323 3.7742 2.1290 虽然使用上面的方法有效,但比使用MATLAB的数组操作功能要慢。复制avg_temp,使得它与temps有同样的大小,然后再做减法,这样就快得多。 ? tdev=temps-avg_temp(ones(31,1),:) tdev = 0.0323 -0.2258 -1.8710 3.0323 0.7742 2.1290 0.0323 -3.2258 -0.8710 2.0323 -0.2258 3.1290 0.0323 -2.2258 2.1290 -0.9677 0.7742 -0.8710 3.0323 0.7742 -4.8710 -3.9677 1.7742 0.1290 7.0323 -1.2258 -1.8710 0.0323 -1.2258 -1.8710 2.0323 1.7742 -0.8710 -0.9677 -0.2258 -2.8710 -2.9677 -1.2258 3.1290 -3.9677 -0.2258 -0.8710 3.0323 -0.2258 -1.8710 -3.9677 0.7742 0.1290 -1.9677 -1.2258 -2.8710 0.0323 -1.2258 2.1290 -2.9677 -0.2258 -0.8710 0.0323 -0.2258 1.1290 0.0323 -0.2258 0.1290 -1.9677 0.7742 -2.8710 1.0323 3.7742 -1.8710 -2.9677 1.7742 0.1290 -1.9677 -2.2258 2.1290 2.0323 -1.2258 1.1290 0.0323 -3.2258 2.1290 1.0323 -1.2258 -1.8710 3.0323 1.7742 3.1290 1.0323 2.7742 4.1290 0.0323 3.7742 2.1290 这里avg_temp(ones(31, 1),:)复制avg_temp的第一行(且仅)31次,创建了一个31×3的矩阵,其第i 列是avg_temp(i)。 ? max_temp=max(temps) max_temp = 19 12 24 找出了每个城市一个月的最高温度。 ? [max_temp, x]=max(temps) max_temp = 19 12 24 x = 9 23 30 找出了每个城市的最高温度和出现最高温度的行下标x。对于这个例子,当发生最高温度时,x辨认了月中的日期。 ? min_temp=min(temps) min_temp = 8 5 15 找出了各城市一个月的最低温度。 ? [min_temp, n]=min(temps) min_temp = 8 5 15 n = 8 3 7 找出了每个城市的最低温度和出现最低温度时行下标n。对于这个例子,当发生最低温度时,n辨认月中的日期。 ? s_dev=std(temps) s_dev = 2.5098 1.7646 2.2322 找出temps的标准偏差。 ? daily_change=diff(temps) daily_change = 3 1 4 -3 -4 -3 2 3 4 -2 -2 -1 -1 3 -3 4 0 -4 -7 1 5 11 -3 -2 -7 0 0 2 3 1 -3 -2 -2 -2 -1 6 -1 1 -4 7 0 -1 -7 1 2 2 -2 -3 2 0 5 -3 1 -3 3 0 2 0 0 -1 -2 1 -3 3 3 1 -4 -2 2 1 -4 2 4 1 -1 -2 -2 1 1 2 -4 2 3 5 -2 1 1 -1 1 -2 计算每日高温之间的偏差,它描述了逐天日高温的变化有多大。例如,daily_change的第一行是每月的第一天和第二天之间的日温度变化量。 9.1 数据分析函数 在MATLAB里的数据分析是按面向列矩阵而进行的。不同的变量存储在各列中,而每行表示每个变量的不同观察。MATLAB统计函数包括 表9.1 数 据 分 析 函 数  corrcoef(x) 求相关系数  cov(x) 协方差矩阵  cplxpair(x) 把向量分类为复共轭对  cross(x, y) 向量的向量积  cumprod(x) 列累计积  cumsum(x) 列累计和  del2(A) 五点离散拉氏算子  diff(x) 计算元素之间差  dot(x, y) 向量的点积  gradient(Z, dx, dy) 近似梯度  histogram(x) 直方图和棒图  max(x), max(x, y) 最大分量  mean(x) 均值或列的平均值  median(x) 列的中值  min(x), min(x, y) 最小分量  prod(x) 列元素的积  rand(x) 均匀分布随机数  randn(x) 正态分布随机数  sort(x) 按升序排列  std(x) 列的标准偏差  subspace(A, B) 两个子空间之间的夹角  sum(x) 各列的元素和   9.2 M文件举例 在这一章里,说明在精通MATLAB工具箱里的两个函数。这些函数说明了本章所示的min和max函数的变种和如何编写一个M文件。关于M文件的更多信息,参阅第8章。 在讨论M文件函数mmin和mmax的内部结构之前,考虑他们有什么功能。 ? amn_temp=mmin(temps) amn_temp = 5 ? [m , i]=mmin(temps) m = 5 i = 3 2 ? amx_temp=mmax(temps) amx_temp = 24 ? [m , j]=mmax(temps) m = 24 j = 30 3 具有一个输出参量的函数mmin找出矩阵中的单个最小值。用第二个输出参量,返回单个最小值的行和列的下标。除了mmax返回矩阵中的单个最大值外,函数mmax的工作方式与mmin相同。这些M文件的函数是: function [m , i]=mmin(a) % MMIN Matrix minimum value. % MMIN(A) returns the minimum value in the matrix A % [M,I] = MMIN(A) in addition returns the indices of % the minimum value in I = [row col]. % Copyright (c) 1996 by Prentice Hall,Inc. if nargout==2, % return indices [m , i]=min(a) ; [m , ic]=min(m) ; i=[i(ic) ic] ; else, m=min(min(a)); end function [m , i]=mmax(a) % MMAX Matrix maximum value. % MMAX(A) returns the maximum value in the matrix A % [M,I] = MMAX(A) in addition returns the indices of % the maximum value in I = [row col]. % Copyright (c) 1996 by Prentice Hall,Inc. if nargout==2, % return indices [m , i]=max(a) ; [m , ic]=max(m) ; i=[i(ic) ic] ; else, m=max(max(a)) ; end