【问题标题】:Undefined function 'real' for input arguments of type 'cell''cell' 类型的输入参数的未定义函数 'real'
【发布时间】:2012-10-03 15:05:52
【问题描述】:

我正在尝试处理数据集,计算条目的出现次数小于给定错误率,为每个数据集 (X) 绘制一个条形图和出现次数 (Y)。似乎count的输出是存储在cell类型中的,bar无法识别。如何将其存储在数组中,而不是单元格类型中?


DATASET_SIZE = 100;
PRUN_MAX_ERROR = 2;
PRUN_MISSING_DATA = -1.000;
ERROR_RATE = 0.2;

for i=1:DATASET_SIZE
   fid = fopen(strcat('log',int2str(i),'.txt'),'r');
   C(i) = textscan(fid, '%.3f');            
   fclose(fid);
end

%% convert cell type to matrix & process data
for i=1:DATASET_SIZE   
   D = cell2mat(C(i));
   %     removing unwanted entries
   D(D == PRUN_MISSING_DATA) = [];      
   D(D > PRUN_MAX_ERROR) = [];       

   %     count number of occurence below certain error rate
   % E = [E sum(D <= ERROR_RATE)];
   E{i} = sum(D <= ERROR_RATE);
end 

figure;
bar(E);

但我得到这个错误:

Undefined function 'real' for input arguments
of type 'cell'.

Error in xychk (line 42)
    x = real(y); y = imag(y);

Error in bar (line 54)
        [msg,x,y] =
        xychk(args{1:nargs},'plot');

Error in checkSeqEffects (line 53)
bar(E); 

【问题讨论】:

    标签: matlab


    【解决方案1】:

    这里有很多问题。在解决真正的问题之前,我将首先讨论它们中的每一个。

    首先是行

    D = cell2mat(C(i));
    

    可以替换为

    D = C{i};
    

    圆括号 (()) 指的是 元胞数组索引,而花括号 ({}) 指的是给定元胞数组的 内容元胞数组索引。重要的是你要学会区别。

    然后,您正在循环内增长单元数组E。这意味着循环将运行得比它需要的慢。只是在循环之前声明它

    E = cell(DATASET_SIZE,1);
    for i=1:DATASET_SIZE
        ...
        E{i} = ...
    end
    

    会加快速度。

    那么,变量名称i 应该避免使用,因为它也表示复杂的单元。 j 也是如此。调用循环索引iijj 将避免Matlab 必须查找您的意思是复杂单元(在Matlab 中正确写为1i1j)或循环索引,这将节省一些时间,最重要的是,避免任何混淆。

    现在,实际问题:bar(E)。在 Matlab 命令提示符中键入 help bar 会显示:

    条形图。

    BAR(X,Y) draws the columns of the M-by-N matrix Y as M groups of N
    vertical bars.  The vector X must not have duplicate values.
    

    这告诉您bar() 需要一个 m×n 矩阵,而您正在向它传递一个 cell-array。最快的解决方法是

    bar([E{:}].')
    

    但这需要很长时间来解释:) 更好的方法是永远不要让E 成为一个单元数组(不需要):

    % convert cell type to matrix & process data
    E = zeros(DATASET_SIZE,1);
    for ii = 1:DATASET_SIZE   
    
       D = C{ii};
    
       % remove unwanted entries
       D(D == PRUN_MISSING_DATA) = [];      
       D(D > PRUN_MAX_ERROR) = [];       
    
       % count number of occurrences below certain error rate       
       E(ii) = sum(D <= ERROR_RATE);
    end 
    
    figure, clf, hold on
    bar(E)
    

    现在E 是一个普通数组,所以bar(E) 可以正常工作。

    我建议您阅读元胞数组,了解何时使用它们,更重要的是,何时不使用。 Stack Overflow(在“matlab”标签中)有大量问题涉及或涉及元胞数组,其中许多还讨论了它们的正确(和不正确)用法和正确(和不正确)用例。

    【讨论】:

    • 感谢罗迪,我从 matlab 收到有关动态 E 大小的警告,但我不知道如何解决它。反正。这非常有帮助!
    • 啊,我没有意识到j 也用于复数!废话,我的函数充满了j 的循环:-( Cheers Rody
    • @ColinTBowers:是的,它在电子和衍生领域更为常见,其中i 通常表示电流。
    【解决方案2】:

    你试过换这两条线吗?

       E = [E sum(D <= ERROR_RATE)];
       % E{i} = sum(D <= ERROR_RATE);
    

    第一个将创建一个普通数组,第二个将创建一个单元矩阵。可能会更好

    E(i) = sum(D <= ERROR_RATE)
    

    即使用圆括号代替大括号。购买这假设 sum(D sum(sum(D <= ERROR_RATE)) 如果你是(即你正在制作一个普通的 2D 条形图,而不是 3D 条形图)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多