计算存储在元胞数组元胞数组中的数据的标准差
Calculating standard deviation on data stored in a cell array of cell arrays
我有一个大小为 A
Mx3 的元胞数组,其中每个条目都包含一个大小为 Nx1 的元胞数组,例如当 M=9 和 N=5 时:
任何给定元胞数组中包含的所有数据均采用矢量格式且长度相等。例如,A{1,1}
包含 5 个大小为 1x93 的向量,而 A{1,2}
包含 5 个大小为 1x100 的向量:
我希望对 27 个单元中的每一个执行此过程:
B = transpose(cell2mat(A{1,1}));
B = sort(B);
C = std(B,0,2); %Calculate standard deviation
最终,对于上述示例,所需的结果将是 27 列 (9x3),其中包含按 A{1,1}
、A{1,2}
、A{1,3}
、A{2,1}
、A{2,2}
、A{2,3}
等等。
我可以通过将上面的代码包装成一个循环来以正确的顺序遍历 27 个单元格中的每一个单元格来做到这一点但是,我想知道是否有一个聪明的 cellfun 或更简洁的方法来完成这个特别是没有使用循环?
您可能应该意识到 cellfun
本质上是对单元格的美化 for
循环。只需进行额外的错误检查以及确保整个工作正常进行的所有操作。无论如何,是的,可以在单个 cellfun
调用中完成您的要求。请注意,我将简单地应用与在 cellfun
的 for
循环中相同的逻辑。另请注意,因为您使用的是元胞数组,所以您别无选择,只能遍历整个主元胞数组。但是,您要做的是在最终元胞数组的每个输出中填充每个结果列向量,以便它们都共享相同的长度。我们可以通过另外两个 cellfun
调用来做到这一点 - 一个用于确定最大向量长度,另一个用于执行填充操作。
类似这样的方法可行:
% Step #1 - Sort the vectors in each cell array, then find row-wise std
B = cellfun(@(x) std(sort(cell2mat(x).'), 0, 2), A, 'un', 0);
% Step #2 - Determine the largest length vector and pad
sizes = cellfun(@numel, B);
B = cellfun(@(x) [x; nan(max(sizes(:)) - numel(x), 1)], B, 'un', 0);
第一行代码获取A
中的每个元素,将每个单元格元素转换为N x 5
列矩阵(即cell2mat(x).'
),然后我们用sort
,然后逐行取标准差。因为输出最终是一个向量,所以我们必须确保 'UniformOutput'
标志为 0,即 'un=0'
。完成标准偏差计算后,我们确定所有单元格元素的每个结果列向量的元素总数,确定 最大 大小,然后使用另一个 cellfun
调用来填充这些向量所以它们都匹配相同的大小。
要最终获得所需的输出,您需要转置元胞数组,然后按列主要顺序展开元素。请记住,MATLAB 访问主要列中的内容,因此以行主要(您想要的)而不是列主要获取内容的常见技巧是首先转置,然后以列主要方式展开以执行行主要读出。在一行中执行此操作很棘手,因此您不仅需要转置元胞数组,还必须使用 reshape
确保以行主要格式读出元素,然后确保放置结果在一行单元格中,然后调用 cell2mat
以便您可以将这些向量拼凑在一起。最终结果应该是一个 27 列的矩阵,其中我们以单行方式将所有这些向量拼凑在一起:
C = cell2mat(reshape(B.', 1, []));
我有一个大小为 A
Mx3 的元胞数组,其中每个条目都包含一个大小为 Nx1 的元胞数组,例如当 M=9 和 N=5 时:
任何给定元胞数组中包含的所有数据均采用矢量格式且长度相等。例如,A{1,1}
包含 5 个大小为 1x93 的向量,而 A{1,2}
包含 5 个大小为 1x100 的向量:
我希望对 27 个单元中的每一个执行此过程:
B = transpose(cell2mat(A{1,1}));
B = sort(B);
C = std(B,0,2); %Calculate standard deviation
最终,对于上述示例,所需的结果将是 27 列 (9x3),其中包含按 A{1,1}
、A{1,2}
、A{1,3}
、A{2,1}
、A{2,2}
、A{2,3}
等等。
我可以通过将上面的代码包装成一个循环来以正确的顺序遍历 27 个单元格中的每一个单元格来做到这一点但是,我想知道是否有一个聪明的 cellfun 或更简洁的方法来完成这个特别是没有使用循环?
您可能应该意识到 cellfun
本质上是对单元格的美化 for
循环。只需进行额外的错误检查以及确保整个工作正常进行的所有操作。无论如何,是的,可以在单个 cellfun
调用中完成您的要求。请注意,我将简单地应用与在 cellfun
的 for
循环中相同的逻辑。另请注意,因为您使用的是元胞数组,所以您别无选择,只能遍历整个主元胞数组。但是,您要做的是在最终元胞数组的每个输出中填充每个结果列向量,以便它们都共享相同的长度。我们可以通过另外两个 cellfun
调用来做到这一点 - 一个用于确定最大向量长度,另一个用于执行填充操作。
类似这样的方法可行:
% Step #1 - Sort the vectors in each cell array, then find row-wise std
B = cellfun(@(x) std(sort(cell2mat(x).'), 0, 2), A, 'un', 0);
% Step #2 - Determine the largest length vector and pad
sizes = cellfun(@numel, B);
B = cellfun(@(x) [x; nan(max(sizes(:)) - numel(x), 1)], B, 'un', 0);
第一行代码获取A
中的每个元素,将每个单元格元素转换为N x 5
列矩阵(即cell2mat(x).'
),然后我们用sort
,然后逐行取标准差。因为输出最终是一个向量,所以我们必须确保 'UniformOutput'
标志为 0,即 'un=0'
。完成标准偏差计算后,我们确定所有单元格元素的每个结果列向量的元素总数,确定 最大 大小,然后使用另一个 cellfun
调用来填充这些向量所以它们都匹配相同的大小。
要最终获得所需的输出,您需要转置元胞数组,然后按列主要顺序展开元素。请记住,MATLAB 访问主要列中的内容,因此以行主要(您想要的)而不是列主要获取内容的常见技巧是首先转置,然后以列主要方式展开以执行行主要读出。在一行中执行此操作很棘手,因此您不仅需要转置元胞数组,还必须使用 reshape
确保以行主要格式读出元素,然后确保放置结果在一行单元格中,然后调用 cell2mat
以便您可以将这些向量拼凑在一起。最终结果应该是一个 27 列的矩阵,其中我们以单行方式将所有这些向量拼凑在一起:
C = cell2mat(reshape(B.', 1, []));