从 MATLAB 元胞数组中删除非数值数据

Removing non-numeric data from MATLAB cell arrays

我有一个包含字符串标识符的 4x1 元胞数组,以及一个 4x5 元胞数组,其中每个实体随着时间的推移包含 5 个数据点...

>> ids = { '1'; '2'; 'A'; '4' }

ids = 

 '1'
 '2'
 'A'
 '4'

>> vals = { 11, 12, 13, 14, 15; 21, 22, 23, 24, 25; 31, 32, 33, 34, 35;, 41, 42, 43, 44, 45}

vals = 

 [11]    [12]    [13]    [14]    [15]
 [21]    [22]    [23]    [24]    [25]
 [31]    [32]    [33]    [34]    [35]
 [41]    [42]    [43]    [44]    [45]

我想将 ID 转换为数字并去除非数字 ID 的两个元胞数组中的数据,留下:

ids = 

 [1]
 [2]
 [4]

vals = 

 [11]    [12]    [13]    [14]    [15]
 [21]    [22]    [23]    [24]    [25]
 [41]    [42]    [43]    [44]    [45]

我想知道这样做的关键是否是找出哪些索引为空,然后使用这些索引对两个元胞数组进行寻址,但我不确定此后该去哪里...

>> numericIds = cellfun(@str2num, ids, 'un', 0)

numericIds = 

 [1]
 [2]
 []
 [4]

>> emptyIdx = cellfun(@isempty, numericIds, 'un', 0)

emptyIdx = 

 [0]
 [0]
 [1]
 [0]

>> ids(emptyIdx) = []
Error using subsindex
Function 'subsindex' is not defined for values of class 'cell'.

对于使用 emptyIdxcellfun 的第二次调用,不要将 UniformOutput 标志指定为 0。删除该选项,它将创建一个逻辑向量,您可以用于直接索引到您的元胞数组,您可以删除条目。

因此,您可以这样做:

emptyIdx = cellfun(@isempty, numericIds);

执行此操作后,您可以使用逻辑索引删除受影响的行:

ids(emptyIdx) = [];
vals(emptyIdx,:) = [];

这是一个 运行 示例:

>> ids = { '1'; '2'; 'A'; '4' }

ids = 

    '1'
    '2'
    'A'
    '4'

>> numericIds = cellfun(@str2num, ids, 'un', 0)

numericIds = 

    [1]
    [2]
    []
    [4]

>> emptyIdx = cellfun(@isempty, numericIds)

emptyIdx =

     0
     0
     1
     0

>> vals = { 11, 12, 13, 14, 15; 21, 22, 23, 24, 25; 31, 32, 33, 34, 35;, 41, 42, 43, 44, 45}

vals = 

    [11]    [12]    [13]    [14]    [15]
    [21]    [22]    [23]    [24]    [25]
    [31]    [32]    [33]    [34]    [35]
    [41]    [42]    [43]    [44]    [45]

>> vals(emptyIdx,:) = []

vals = 

    [11]    [12]    [13]    [14]    [15]
    [21]    [22]    [23]    [24]    [25]
    [41]    [42]    [43]    [44]    [45]

>> ids(emptyIdx) = []

ids = 

    '1'
    '2'
    '4'

正如其他人所说,问题的根源在于您试图使用元胞数组作为索引。这是因为 cellfununiform 输入决定是否 return 元胞数组 (false) 的数值数组 (true).

话虽如此,我可能不会使用 cellfun,可能只是直接在元胞数组上使用 str2double 来确定哪些是有效数字(它 return 是一个NaN 表示非数字)。

ids = str2double(ids);
tokeep = ~isnan(ids);
ids = ids(tokeep);
vals = vals(tokeep, :)

NOTE: In general, most functions that operate on strings (such as str2double) also operate on cell arrays of strings.