简体   繁体   English

具有多个输出的 Matlab `rowfun` 函数:假设行顺序安全吗?

[英]Matlab `rowfun` function with multiple outputs: Safe to assume row order?

I tried providing a function to rowfun that returns multiple-row output, of the same height as the input.我尝试为rowfun提供一个函数,该函数返回与输入高度相同的多行输出。 It seems to work as expected.似乎按预期工作。

% Example table with 2-column-array as a single data field
x = table( [1;1;2;2] , [[2;2;1;1] [2;1;2;1]] , ...
           'VariableNames' , {'idx' 'Field2columns'} )

  x = idx    Field2columns
      ___    _____________
      1      2    2       
      1      2    1       
      2      1    2       
      2      1    1       

% Example anonymous function takes all rows with same idx value and
% reverse their row order
y = rowfun( @(z) z(end:-1:1,:) , x , 'Input','Field2columns' , ...
            'Grouping','idx' , 'OutputVar','OutVar' )

  y =        idx    GroupCount    OutVar
             ___    __________    ______
      1      1      2             2    1
      1_1    1      2             2    2
      2      2      2             1    1
      2_1    2      2             1    2

% Append the generated data to original table
[ x y(:,{'OutVar'}) ]

  ans =      idx    Field2columns    OutVar
             ___    _____________    ______
      1      1      2    2           2    1
      1_1    1      2    1           2    2
      2      2      1    2           1    1
      2_1    2      1    1           1    2

This makes for very efficient code.这使得代码非常高效。 I would otherwise have to loop through all distinct values of x.idx , extract matching rows of x for each value, generate row-reversed subset and compile the results.否则,我将不得不遍历x.idx所有不同值,为每个值提取x匹配行,生成行反转子集并编译结果。

My only concern is that I am assuming that the row order of the output from the anonymous function will be maintained, and that each row will align with the corresponding row in table x .我唯一担心的是,我假设匿名函数输出的行顺序将保持不变,并且每一行都将与表x的相应行对齐。 For example, if idx=7, then the Nth row in x for which idx=7 will be appended on the right with Nth row in anonymous function output when it is applied to x(x.idx==7,:) .例如,如果 idx=7,那么当它应用于x(x.idx==7,:)时, x中 idx=7 的第 N 行将附加到匿名函数输出中的第 N 行。

The rowfun documentation doesn't deal with cases in which the first argument represents a function that returns a multi-row output. rowfun文档不处理第一个参数表示返回多行输出的函数的情况。 I have only the observed behaviour to rely on.我只有观察到的行为可以依赖。 Would it be advisable to exploit this behaviour to streamline my code, or is it bad practice to rely on such undocumented behaviour, eg, corner cases may not be covered, and there is no obligation for TMW to maintain current behaviour in the future?利用这种行为来简化我的代码是可取的,还是依赖这种未记录的行为是一种不好的做法,例如,可能不包括极端情况,并且 TMW 没有义务在未来保持当前行为?

The documentation for rowfun , under 'GroupingVariables' says: 'GroupingVariables''GroupingVariables' rowfun 文档说:

The output, B, contains one row for each group.输出 B 包含每一组的一行。

So if you get more than one row per group, you are definitely treading in undocumented waters.因此,如果您每组获得不止一排,那么您肯定是在无证水域。 A future version could throw an error with your code.未来的版本可能会在您的代码中引发错误。

Regarding the order of the input rows to your function: I would suggest you ask MathWorks about the order of the rows with the same grouping variables.关于函数输入行的顺序:我建议您向 MathWorks 询问具有相同分组变量的行的顺序。 One way would be to go to the bottom of the documentation page, select a star rating, then in the text box say that the documentation isn't complete because it doesn't specify the order of the rows when this option is given.一种方法是转到文档页面的底部,选择星级,然后在文本框中说文档不完整,因为在给出此选项时它没有指定行的顺序。 The documentation folk like the docs being thorough and complete, they might answer this question by completing the documentation.喜欢文档的人喜欢彻底和完整的文档,他们可能会通过完成文档来回答这个问题。

If you want to stay in the documented zone, you can use the very handysplitapply for that.如果你想留在记录区域,你可以使用非常方便的splitapply To deal with the multiple rows in the output you can put them in a cell, and then convert it to a table:要处理输出中的多行,您可以将它们放在一个单元格中,然后将其转换为表格:

y = splitapply(@(z) {z(end:-1:1,:)},x.Field2columns,x.idx) % note the {...} in the function
[x table(cell2mat(y),'VariableNames',{'OutVar'})] % this is like: [x y(:,{'OutVar'})]

I guess this will be less efficient, but it keeps your code within the documented behaviour of the functions, without a need to use loops.我猜这会降低效率,但它使您的代码保持在函数的记录行为内,而无需使用循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM