【问题标题】:Build a matrix starting from instances of structure fields in MATLAB从 MATLAB 中的结构体字段的实例开始构建矩阵
【发布时间】:2018-07-12 21:01:36
【问题描述】:

我真的很抱歉打扰,所以我希望这不是一个愚蠢或重复的问题。 我一直在抓取一个网站,将结果保存为 MongoDB 中的集合,将其导出为 JSON 文件并将其导入 MATLAB。 在故事的最后我得到了一个struct 组织的对象 like this one in the picture.

我感兴趣的是最后两个元胞数组(可以使用string() 轻松转换为字符串数组)。第一个元胞数组是 keys 的集合(想想独特的产品),第二个元胞数组是 values 的集合(想想价格),就像字典一样。每个字段都是一组此键的可能值的实例(想想每日价格)。我的目标是构建一个像这样制作的矩阵

KEYS   VALUES_OF_FIELD_1   VALUES_OF_FIELD2   ...   VALUES_OF_FIELDn
A             x                   x                        x
B             x                   z                       NaN
C             z                   x                        y
D            NaN                  y                        x
E             y                   x                        z

主要问题是,如图所示,正如我试图在示例矩阵中解释的那样,我并不总是对每个字段中的所有键都有一个值(如您所见,有时它们是 321,其他时候是 319 或 320 或 317),因此第一个数组中缺少键。在这种情况下,我应该用 NaN 填充缺失值。键可以按字母顺序排列并且都是唯一的。

您认为在 MATLAB 中解决此问题的最佳和最具可扩展性的方法是什么?

非常感谢您抽出宝贵时间,希望我能清楚地解释自己。

编辑: 在我的例子中,这两个数组都是由字符串组成的,所以类型不是问题(我已经修改了这个例子)。主要问题是,由于每个字段的键不同,首先我必须找到结构中的所有(唯一)键,以构建行,然后对于每一列(字段),我必须填充值,将 NaN钥匙丢失的地方。

【问题讨论】:

    标签: matlab matrix data-structures data-science


    【解决方案1】:

    要记住的一点是,您不能简单地在一个矩阵中同时使用字符串和数字。因此,如果将它们组合在一起,它们可以是所有字符串或所有数字。我认为所有字符串都适合你。

    在制作矩阵之前,请确保所有单元格都具有相同的元素。

    new_matrix = horzcat(keys,values1,...valuesn); 
    

    这将为每一行提供一个矩阵(根据您的图像)。现在您可以使用 for 循环来获取所有行的矩阵。

    【讨论】:

    • 我忘了指定在我的情况下两者都是字符串数组,所以这不是问题。主要问题是我有一个可变的键数组,首先我必须在结构中找到所有可能的键来构建行。然后我必须填充矩阵,在该列(字段)中不存在特定键的情况下放置 NaN。
    • 那么,您必须在其中找到所有可用的键,然后将它们合并在一起吗?到目前为止,您尝试过什么?可以加代码吗?
    • 是的,找到并合并所有键是主要问题。我将发布我的部分解决方案作为答案。感谢您的关注。
    【解决方案2】:

    目前,我通过将结构中最长的键数组视为完整的键集来解决它,我们称之为keys_set

    然后我以这种方式为结构中的每个字段创建了一个 Map 对象:

    for i=1:length(structure)
        structure(i).myMap = containers.Map(structure(i).key_field, structure(i).value_field);
    end
    

    然后我通过对照keys_set 数组检查每个地图来构建我的矩阵 (M):

    for i=1:length(keys_set)
        for j=1:length(structure)
           if isKey(structure(j).myMap,char(keys_set(i)))
               M(i,j) = string(structure(j).myMap(char(keys_set(i))));
           else
               M(i,j) = string('MISSING');
           end
        end
    end
    

    这可行,但最好还能够检查keys_set 是否真的完整。

    编辑:我已经通过using this function 解决了我的问题并构建了所有可能键的正确集合:

    %% Finding the maximum number of keys in all the fields
    maxnk = length(structure(1).key_field);
    for i=2:length(structure)
        if length(structure(i).key_field) > maxnk
            maxnk = length(structure(i).key_field);
        end
    end
    
    %% Initialiting the matrix containing all the possibile set of keys
    keys_set=string(zeros(maxnk,length(structure)));
    
    %% Filling the matrix by putting "0" if the dimension is smaller
    for i=1:length(structure)
        d = length(string(structure(i).key_field));
        if  d == maxnk
            keys_set(:,i) = string(structure(i).key_field);
        else
            clear tmp
            tmp = [string(structure(i).key_field); string(zeros(maxnk-d,1))];
            keys_set(:,i) = tmp;
        end
    end
    
    %% Merging without duplication and removing the "0" element
    keys_set = union_several(keys_set);
    keys_set = keys_set(keys_set ~= string(0));
    

    【讨论】:

    • 有没有确定的方法来确定密钥?假设密钥必须在 A 到 Z 之间,还是只是随机的?你确定keys_set的程序是什么?
    • 钥匙就像物品离开或进入目录,所以在某些情况下我们拥有它们,而在另一种情况下我们可能没有。现在我只取最大的键数组(假设没有证据证明另一个都是这个的子数组)并将其用作keys_set。但是正如您所说,最好的方法是检查所有键数组并合并它们而不重复,但现在我不知道该怎么做。
    • 谢谢,我找到了一个社区功能,可以合并两个以上的数组,我已经用正确的解决方案编辑了我的答案。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2015-01-06
    • 2011-02-18
    • 1970-01-01
    • 2011-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多