在 MATLAB 中用两个值替换向量值
Substitute a vector value with two values in MATLAB
我必须创建一个函数,它将一个向量 v
和三个标量 a
、b
和 c
作为输入。该函数用双元素数组 [b,c]
.
替换 v
中等于 a
的每个元素
例如,给定 v = [1,2,3,4]
和 a = 2, b = 5, c = 5
,输出将是:
out = [1,5,5,3,4]
我的第一次尝试是尝试这个:
v = [1,2,3,4];
v(2) = [5,5];
但是,我得到一个错误,所以我不明白如何将两个值放在向量中的一个位置,即将所有以下值向右移动一个位置,以便新的两个值适合向量,因此,向量的大小将增加一。另外,如果v
中存在多个a
的值,我不知道如何一次性全部替换掉。
如何在 MATLAB 中执行此操作?
我要做的是首先找到 v
等于 a
的值,我们称之为 ind
。然后,创建一个输出大小等于 numel(v) + numel(ind)
的新输出向量,因为我们将 v
中 a
的每个值替换为一个附加值,然后使用索引放置我们的新价值观。
假设您已经创建了一个行向量v
,请执行以下操作:
%// Find all locations that are equal to a
ind = find(v == a);
%// Allocate output vector
out = zeros(1, numel(v) + numel(ind));
%// Determine locations in output vector that we need to
%// modify to place the value b in
indx = ind + (0:numel(ind)-1);
%// Determine locations in output vector that we need to
%// modify to place the value c in
indy = indx + 1;
%// Place values of b and c into the output
out(indx) = b;
out(indy) = c;
%// Get the rest of the values in v that are not equal to a
%// and place them in their corresponding spots.
rest = true(1,numel(out));
rest([indx,indy]) = false;
out(rest) = v(v ~= a);
indx
和 indy
语句比较棘手,但肯定不难理解。对于 v
中等于 a
的每个索引,发生的情况是我们需要为 v
等于 [=14] 的每个索引/位置将向量移动 1 =].第一个值要求我们将向量向右移动 1,然后下一个值要求我们相对于之前的移动向右移动 1,这意味着我们实际上需要取第二个索引并向右移动 2,因为这是相对于原始索引的。
下一个值要求我们相对于第二次移位右移1,或者相对于原索引右移3等.这些转变定义了我们要放置的位置 b
。要放置 c
,我们只需使用为放置 b
生成的索引并将它们向右移动 1。
剩下的就是用不等于 a
的值填充输出向量。我们简单地定义一个逻辑掩码,其中用于填充输出数组的索引将其位置设置为 false
,而其余位置设置为 true
。我们用这个索引到输出中,找到那些不等于a
的位置来完成赋值。
示例:
v = [1,2,3,4,5,4,4,5];
a = 4;
b = 10;
c = 11;
使用上面的代码,我们得到:
out =
1 2 3 10 11 5 10 11 10 11 5
这成功地将 v
中的每个值 4 替换为 [10,11]
的元组。
您没有试图覆盖向量中的现有值。您正在尝试更改向量的大小(即向量中的行数或列数),因为您正在添加一个元素。这将始终导致向量在内存中重新分配。
创建一个新向量,使用 v 的前半部分和后半部分。
假设您的索引存储在变量 index 中。
index = 2;
newValues = [5, 5];
x = [ v(1:index), newValues, v(index+1:end) ]
x =
1 2 5 5 3 4
这是一个使用元胞数组的解决方案:
% remember the indices where a occurs
ind = (v == a);
% split array such that each element of a cell array contains one element
v = mat2cell(v, 1, ones(1, numel(v)));
% replace appropriate cells with two-element array
v(ind) = {[b c]};
% concatenate
v = cell2mat(v);
和rayryeng的解决方案一样,它可以替换多次出现的a
。
siliconwafer 提到的数组改变大小的问题,这里通过将部分数组中间保留在元胞数组的元胞中来解决。转换回数组会合并这些部分。
我认为 strrep
值得一提。
虽然它被称为 字符串替换 并警告非字符输入,但它对于其他数字(包括整数、双精度甚至复数)仍然可以正常工作。
v = [1,2,3,4]
a = 2, b = 5, c = 5
out = strrep(v, a, [b c])
Warning: Inputs must be character arrays or cell arrays of strings.
out =
1 5 5 3 4
我必须创建一个函数,它将一个向量 v
和三个标量 a
、b
和 c
作为输入。该函数用双元素数组 [b,c]
.
v
中等于 a
的每个元素
例如,给定 v = [1,2,3,4]
和 a = 2, b = 5, c = 5
,输出将是:
out = [1,5,5,3,4]
我的第一次尝试是尝试这个:
v = [1,2,3,4];
v(2) = [5,5];
但是,我得到一个错误,所以我不明白如何将两个值放在向量中的一个位置,即将所有以下值向右移动一个位置,以便新的两个值适合向量,因此,向量的大小将增加一。另外,如果v
中存在多个a
的值,我不知道如何一次性全部替换掉。
如何在 MATLAB 中执行此操作?
我要做的是首先找到 v
等于 a
的值,我们称之为 ind
。然后,创建一个输出大小等于 numel(v) + numel(ind)
的新输出向量,因为我们将 v
中 a
的每个值替换为一个附加值,然后使用索引放置我们的新价值观。
假设您已经创建了一个行向量v
,请执行以下操作:
%// Find all locations that are equal to a
ind = find(v == a);
%// Allocate output vector
out = zeros(1, numel(v) + numel(ind));
%// Determine locations in output vector that we need to
%// modify to place the value b in
indx = ind + (0:numel(ind)-1);
%// Determine locations in output vector that we need to
%// modify to place the value c in
indy = indx + 1;
%// Place values of b and c into the output
out(indx) = b;
out(indy) = c;
%// Get the rest of the values in v that are not equal to a
%// and place them in their corresponding spots.
rest = true(1,numel(out));
rest([indx,indy]) = false;
out(rest) = v(v ~= a);
indx
和 indy
语句比较棘手,但肯定不难理解。对于 v
中等于 a
的每个索引,发生的情况是我们需要为 v
等于 [=14] 的每个索引/位置将向量移动 1 =].第一个值要求我们将向量向右移动 1,然后下一个值要求我们相对于之前的移动向右移动 1,这意味着我们实际上需要取第二个索引并向右移动 2,因为这是相对于原始索引的。
下一个值要求我们相对于第二次移位右移1,或者相对于原索引右移3等.这些转变定义了我们要放置的位置 b
。要放置 c
,我们只需使用为放置 b
生成的索引并将它们向右移动 1。
剩下的就是用不等于 a
的值填充输出向量。我们简单地定义一个逻辑掩码,其中用于填充输出数组的索引将其位置设置为 false
,而其余位置设置为 true
。我们用这个索引到输出中,找到那些不等于a
的位置来完成赋值。
示例:
v = [1,2,3,4,5,4,4,5];
a = 4;
b = 10;
c = 11;
使用上面的代码,我们得到:
out =
1 2 3 10 11 5 10 11 10 11 5
这成功地将 v
中的每个值 4 替换为 [10,11]
的元组。
您没有试图覆盖向量中的现有值。您正在尝试更改向量的大小(即向量中的行数或列数),因为您正在添加一个元素。这将始终导致向量在内存中重新分配。
创建一个新向量,使用 v 的前半部分和后半部分。
假设您的索引存储在变量 index 中。
index = 2;
newValues = [5, 5];
x = [ v(1:index), newValues, v(index+1:end) ]
x =
1 2 5 5 3 4
这是一个使用元胞数组的解决方案:
% remember the indices where a occurs
ind = (v == a);
% split array such that each element of a cell array contains one element
v = mat2cell(v, 1, ones(1, numel(v)));
% replace appropriate cells with two-element array
v(ind) = {[b c]};
% concatenate
v = cell2mat(v);
和rayryeng的解决方案一样,它可以替换多次出现的a
。
siliconwafer 提到的数组改变大小的问题,这里通过将部分数组中间保留在元胞数组的元胞中来解决。转换回数组会合并这些部分。
我认为 strrep
值得一提。
虽然它被称为 字符串替换 并警告非字符输入,但它对于其他数字(包括整数、双精度甚至复数)仍然可以正常工作。
v = [1,2,3,4]
a = 2, b = 5, c = 5
out = strrep(v, a, [b c])
Warning: Inputs must be character arrays or cell arrays of strings.
out =
1 5 5 3 4