在 MATLAB 中用两个值替换向量值

Substitute a vector value with two values in MATLAB

我必须创建一个函数,它将一个向量 v 和三个标量 abc 作为输入。该函数用双元素数组 [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) 的新输出向量,因为我们将 va 的每个值替换为一个附加值,然后使用索引放置我们的新价值观。

假设您已经创建了一个向量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);

indxindy 语句比较棘手,但肯定不难理解。对于 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