MATLAB:如何根据同一参考创建具有多个值的元胞数组
MATLAB: How to create cell arrays with multiple values in correspondence of the same reference
我知道我的问题比较具体,但还是希望能在这里找到答案,希望以后能对更多人有所帮助。
我有不同的参考区间,它表示时间段,以及与每个时间段关联的不同值。例如:
starts = [17;249;17]; % starting points for the time periods
ends = [25;257;25]; % endingpoints for the time periods
values = [1; 2; 3]; % values to assign in correspondence of each interval
如果你注意到,第一个和第三个周期是相同的(相同的开始和结束参考值,17-25)因此值 1 和 3 可以与相同的周期相关联。
因此我想获得两个数组,一个列出每个时期的时间步长,另一个列出每个时期的相关值。我只能重复每个时期的时间步长,这样做:
time_cell = cell (length(starts),1);
values_cell = cell (length(starts),1);
values_repeated = cell (1,length(starts));
for i= 1:length(starts)
time_cell{i,1}= (starts(i,1):1:ends(i,1))';
values_cell{i,1}= values(i);
values_repeated{:,i} = repmat(values_cell(i,1),length(time_cell {i,1}),1);
end
all_times_numeric = cell2mat(time_cell(:,1));
all_values = cat(1,values_repeated{:,:})
这让我获得:
all_values =
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
我可以使用函数 unique 消除 all_times_numeric 中的重复项,但我正在努力寻找一种方法来合并对应于同一时期的值,例如
all_values =
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
或
all_values =
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
有没有一种方法可以使用示例中实现的 for 循环来获取这些数组中的任何一个,并针对任何情况扩展结果(任何 start/end 周期、与相同周期关联的更多值等) ?非常感谢!
这里有一个选项:
starts = [17;249;17]; % starting points for the time periods
ends = [25;257;25]; % ending points for the time periods
values = [1; 2; 3]; % values to assign in correspondence of each interval
all_values = zeros(max(ends),max(values));
for k = 1:length(starts)
all_values(starts(k):ends(k),values(k)) = values(k);
end
all_values = all_values(sum(all_values,2)>0,:);
all_values = arrayfun(@(r) nonzeros(all_values(r,:)).',...
1:length(all_values),'UniformOutput',false).'
到最后一行之前,add_values
是一个矩阵大小max(ends)
-by-max(values)
,看起来像这样:
all_values =
1 0 3
1 0 3
1 0 3
.
.
.
0 2 0
0 2 0
因此对于每个时间步长,我们都有一行在不同的列中包含匹配值。现在我们要去掉所有的零,只保留每行中的非零数字。所以我们定义新的匿名函数:
@(r) nonzeros(all_values(r,:)).'
得到一行 r
,并且 return 在 all_values(r,:)
中所有不为零的值。 nonzeros
的输出是一列,因此为了将结果保持为一行,我们添加了 .'
(转置)。现在我们想在所有行上应用它,所以我们使用 arrayfun
:
arrayfun(function_handle,1:length(all_values)).'
这会将我们刚刚定义的 function_handle
中的函数应用于 1:length(all_values)
中的所有元素,这些元素只是 all_values
中的所有行号。但是,由于我们函数的输出大小不同,我们需要关闭 'UniformOutput'
选项,因此每个元素的结果存储在元胞数组的不同单元格中。 arrayfun
的输出是一行,所以为了得到作为列的结果,我们添加了 .'
(转置)。所以我们得到:
all_values =
[1x2 double]
[1x2 double]
[1x2 double]
.
.
.
[ 2]
[ 2]
我知道我的问题比较具体,但还是希望能在这里找到答案,希望以后能对更多人有所帮助。
我有不同的参考区间,它表示时间段,以及与每个时间段关联的不同值。例如:
starts = [17;249;17]; % starting points for the time periods
ends = [25;257;25]; % endingpoints for the time periods
values = [1; 2; 3]; % values to assign in correspondence of each interval
如果你注意到,第一个和第三个周期是相同的(相同的开始和结束参考值,17-25)因此值 1 和 3 可以与相同的周期相关联。
因此我想获得两个数组,一个列出每个时期的时间步长,另一个列出每个时期的相关值。我只能重复每个时期的时间步长,这样做:
time_cell = cell (length(starts),1);
values_cell = cell (length(starts),1);
values_repeated = cell (1,length(starts));
for i= 1:length(starts)
time_cell{i,1}= (starts(i,1):1:ends(i,1))';
values_cell{i,1}= values(i);
values_repeated{:,i} = repmat(values_cell(i,1),length(time_cell {i,1}),1);
end
all_times_numeric = cell2mat(time_cell(:,1));
all_values = cat(1,values_repeated{:,:})
这让我获得:
all_values =
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[1]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
[3]
我可以使用函数 unique 消除 all_times_numeric 中的重复项,但我正在努力寻找一种方法来合并对应于同一时期的值,例如
all_values =
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[1 3]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
[2]
或
all_values =
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[1] [3]
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
[2] []
有没有一种方法可以使用示例中实现的 for 循环来获取这些数组中的任何一个,并针对任何情况扩展结果(任何 start/end 周期、与相同周期关联的更多值等) ?非常感谢!
这里有一个选项:
starts = [17;249;17]; % starting points for the time periods
ends = [25;257;25]; % ending points for the time periods
values = [1; 2; 3]; % values to assign in correspondence of each interval
all_values = zeros(max(ends),max(values));
for k = 1:length(starts)
all_values(starts(k):ends(k),values(k)) = values(k);
end
all_values = all_values(sum(all_values,2)>0,:);
all_values = arrayfun(@(r) nonzeros(all_values(r,:)).',...
1:length(all_values),'UniformOutput',false).'
到最后一行之前,add_values
是一个矩阵大小max(ends)
-by-max(values)
,看起来像这样:
all_values =
1 0 3
1 0 3
1 0 3
.
.
.
0 2 0
0 2 0
因此对于每个时间步长,我们都有一行在不同的列中包含匹配值。现在我们要去掉所有的零,只保留每行中的非零数字。所以我们定义新的匿名函数:
@(r) nonzeros(all_values(r,:)).'
得到一行 r
,并且 return 在 all_values(r,:)
中所有不为零的值。 nonzeros
的输出是一列,因此为了将结果保持为一行,我们添加了 .'
(转置)。现在我们想在所有行上应用它,所以我们使用 arrayfun
:
arrayfun(function_handle,1:length(all_values)).'
这会将我们刚刚定义的 function_handle
中的函数应用于 1:length(all_values)
中的所有元素,这些元素只是 all_values
中的所有行号。但是,由于我们函数的输出大小不同,我们需要关闭 'UniformOutput'
选项,因此每个元素的结果存储在元胞数组的不同单元格中。 arrayfun
的输出是一行,所以为了得到作为列的结果,我们添加了 .'
(转置)。所以我们得到:
all_values =
[1x2 double]
[1x2 double]
[1x2 double]
.
.
.
[ 2]
[ 2]