【问题标题】:Substitute a vector value with two values in MATLAB在 MATLAB 中用两个值替换一个向量值
【发布时间】:2015-07-11 13:09:10
【问题描述】:

我必须创建一个函数,该函数将向量v 和三个标量abc 作为输入。该函数将v 中等于a 的每个元素替换为两个元素数组[b,c]

例如,给定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 = [v(1) [5,5] v(3:end)] 会起作用,但取决于您想如何使用它,可能会有更好的答案
  • 我必须创建一个函数,该函数将向量 v 和三个标量 a、b 和 c 作为输入。该函数将 v 中等于 a 的每个元素替换为 b 和 c。
  • @MartaSampietro - 让我明白这一点。如果我们在向量中找到值a,是否每个元素都被替换为 2 元素向量?例如,如果v = [1,2,3,4,5]a = 4b = 10, c = 11,新向量是否变为v = [1,2,3,10,11,5]
  • @MartaSampietro - 我冒昧地更改了您的问题以反映您的评论。您所做的评论是一个严肃的设计元素,在您的第一个问题版本中被省略了。有了这个,很多给你解决问题的cmets现在都失效了。
  • 我们的回答对您有帮助吗?

标签: arrays matlab vector indexing assignment-operator


【解决方案1】:

我认为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

【讨论】:

  • 确实很有趣。
【解决方案2】:

这是一个使用元胞数组的解决方案:

% 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 提到的阵列改变大小的问题,在这里通过将部分阵列中间保留在单元阵列的单元中来解决。转换回数组会连接这些部分。

【讨论】:

  • mat2cell 的好选择。这是一个更容易阅读的解决方案,而不是我纯粹的索引方法。
  • 谢谢@rayryeng。不过,对于较大的数组,您的应该更有效。
  • 很好,尽管您可以进行 2 种简化:1) 使用 num2cellv 转换为元胞数组:v = num2cell(v); 2) 使用以下方法将 v 转换回数值向量逗号分隔的列表,而不是 cell2mat: v = [v{:}];
  • @gnovice,感谢您的评论!我已经想知道为什么将每个数组元素放在一个单元格中这样简单的事情需要如此复杂的语法。
  • 非常感谢,它正是我需要它做的!我没有想过使用元胞数组,而且这种方法似乎效果很好!
【解决方案3】:

我要做的是首先找到等于av 的值,我们将其称为ind。然后,创建一个新的输出向量,其输出大小等于numel(v) + numel(ind),因为我们正在用一个附加值替换v 中的每个a 值,然后使用索引来放置我们的新值。

假设您已经创建了一个 row 向量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 的每个索引,发生的情况是,对于等于av 的每个索引/位置,我们需要将向量移动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 ? OP 似乎已经知道新值所需的索引。
  • @A.Donda - 谢谢先生 :) 也为你 +1。
  • 爱面具!不错的选择。
  • @A.Donda - 我将其替换为 v(v ~= a)。我认为更容易阅读。
  • 那些效率不如这个,但可能很紧凑!
【解决方案4】:

您没有尝试覆盖向量中的现有值。您正在尝试更改向量的大小(即向量中的行数或列数),因为您正在添加一个元素。这将始终导致向量在内存中重新分配。

使用v的前半部分和后半部分创建一个新向量。

假设您的索引存储在变量 index 中。

index = 2;
newValues = [5, 5];
x = [ v(1:index), newValues,  v(index+1:end) ]

x =

     1     2     5     5     3     4

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    • 2011-04-23
    • 2021-08-05
    • 1970-01-01
    • 2021-03-01
    • 2019-05-07
    • 2021-09-27
    相关资源
    最近更新 更多