matlab 如何修复使用cellfun()时从单元格数组中提取空结构字段的错误

j5fpnvbx  于 7个月前  发布在  Matlab
关注(0)|答案(2)|浏览(135)

我在Matlab中有一个单元格数组,每个单元格代表一个金融交易作为结构对象(单元格数组是从json文件导入的)。
下面是一个创建测试集的例子,它复制了我的数据的特征,在这种情况下代表4个单独的事务:

transaction_1 = struct( 'created_on' , '2023-01-22' , 'amount' , 9.60 , 'merchant' , struct('name','ebay') );
transaction_2 = struct( 'created_on' , '2022-11-22' , 'amount' , 6.20 , 'merchant' , struct('name','ikea') );
transaction_3 = struct( 'created_on' , '2019-06-19' , 'amount' , 3.65 , 'merchant' , [] );

transactions = { transaction_1 ; transaction_2 ; transaction_3 };

% Add a fourth which is not "compatible" in dimension with the others
transactions{4} = struct( 'created_on' , '2019-06-19' , 'amount' , 1.25 , 'merchant' , [] , 'location' , 'London');

单元数组中的每个结构都包含三个字段:
1.交易的日期
1.交易金额
1.第三个字段表示商家的名称。如果没有商家信息,则此字段为空。但是,如果有信息,则此字段是另一个具有字段“name”的结构。
1.一些结构也有一个“位置”字段。
第三个交易在测试集中没有商家信息,所以transactions{3}.merchant返回空,而第四个交易也有位置数据。
现在,我希望从各个结构中提取字段值到单独的单元数组中。下面的代码可以正确地处理日期和金额

created_on = cellfun(@(x) x.created_on , transactions , 'UniformOutput' , false);
amounts = cellfun(@(x) x.amount , transactions , 'UniformOutput' , false);
merchant_names = cellfun(@(x) x.merchant.name , transactions , 'UniformOutput' , false);

但对商家来说是失败的,因为在某些情况下这个名字并不存在。有没有一个很好的方法来做到这一点,而不诉诸于一个循环在所有条目?

iyzzxitl

iyzzxitl1#

您可以创建一个helper函数来处理不同的情况,然后在cellfun中使用它。

merchant_names = cellfun( @(x) structValIfExists(x.merchant, 'name'), transactions, 'uni', 0 );

% >> merchant_names = {'ebay', 'ikea', ''}

function v = structValIfExists( s, fld )
    if isstruct( s ) && isfield( s, fld )
        v = s.(fld);
    else
        v = '';
    end
end
mnowg1ta

mnowg1ta2#

我首先将merchant字段提取到单元数组中,然后对其进行处理。
首先,将结构体的单元数组转换为结构体数组将使一切变得更容易。假设所有的结构都是兼容的,就像你的例子一样,那么我们可以这样做:

transactions = [transactions{:}];

我们现在有一个1x3的struct数组。我们现在可以很容易地将各个字段提取到单元数组中,如下所示:

merchant = {transactions.merchant}

有些单元格将是空数组,其他单元格将是结构。让我们来看看哪个是哪个:

index = ~cellfun('isempty', merchant)

我们现在创建一个包含商家名称的单元数组,并使用商家所在的名称填充它:

merchant_name = cell(size(index));
merchant_name(:) = {''};
merchant_name(index) = {merchant(index).name};

现在merchant_name是单元数组:

merchant_name =

  1x3 cell array

    {'ebay'}    {'ikea'}    {0x0 char}

相关问题