从Matlab数组中提取实数

7
我想从一个包含虚数的数组中仅提取实数。我想从数组中消除虚数。因此,从一个包含10个元素的数组中,其中有5个实数和5个虚数,要获得仅包含5个实数元素的数组。这是在MATLAB中完成的。 编辑: 添加一个例子
input_array = [ 1, 1+i, -2+2*j, 3, -4, j ];

期望的输出结果应该是:
output = [ 1, 3, -4 ];

这个数组只包含 input_array 中的真实元素。

4个回答

12

还有一种更矢量化的方法:

sel = a == real(a); % choose only real elements

only_reals = a( sel );

非常感谢,你可以享受长达150年的健康生活!!! - carminePat

5
您可以使用isreal结合arrayfun检查数字是否为实数和/或real仅保留实部。例如:
a = [1+i 2 3 -1-i];
realidx = arrayfun(@isreal,a);
only_reals = a(realidx);
only_real_part = real(a);

>> only_reals

  = [ 2  3]

>> only_real_part

  = [1 2 3 -1]

+1 我总是忘记 arrayfun。 - HebeleHododo
基本上它也是一个循环,但对于一行代码来说非常方便。 - Gunther Struyf
1
@GuntherStruyf 希望在未来的版本中,所有的*fun函数都能够高效地实现(并行或其他方式...) - Shai
1
realidx 始终为零,only_reals 为空。 - carminePat
@carminePat 不在这里,你把什么放进了 a - Gunther Struyf
当我使用arrayfun应用isreal时,我也只得到了0。 - Confounded

4

实数的虚部为零,因此:

input_array(imag(input_array)==0);

ans =
    1     3    -4

3
你可以使用 isreal 函数来实现。然而,isreal 函数的输出不是向量,这在 MATLAB 中很奇怪,因为通常情况下是向量。所以,你需要使用 for 循环。
arr = [1+i 5 6-3i 8];
arrReal = [];
for idx = 1:numel(arr)
    if isreal(arr(idx))
        arrReal(end+1) = arr(idx);
    end
end

我想这里的大佬会想出一个无需循环的解决方案。

Shai的编辑:

一种预先分配输出结果的版本

arrReal = NaN( size(arr) ); % pre-allocation
for idx = 1:numel(arr)
    if isreal( arr(idx) )
        arrReal(idx) = arr(idx);
    end
end
arrReal( isnan( arrReal ) ) = []; % discard non-relevant entries

当然,可以在不使用循环的情况下实现这个目标(请参阅其他答案)。但是对于这个循环版本,预分配是一个重要的因素。

isreal的用法很有趣。不过你的回答有两个主要缺点:1. 它使用了一个循环(正如你已经注意到的那样)。2. 循环内部arrReal的输出是增长的。这种类型的内存使用会导致Matlab变得非常慢。更好的方法是将arrReal预先分配到arr的大小,并在循环后删除冗余部分。无论如何,感谢你的回答! - Shai
@Shai 我考虑过预分配,但是除了保留另一个索引变量之外,我想不出其他索引arrReal的方法。所以,我决定不这样做。但我可能还是应该这样做。你知道更聪明的方法吗? - HebeleHododo
我刚才编辑了你的答案,并添加了一个预分配版本。希望你喜欢它。 - Shai
1
@Shai,我看到你的编辑被拒绝了。所以我复制了你的解决方案。 - HebeleHododo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接