Функция Matlab `rowfun` с несколькими выходами: безопасно принять порядок строк? - PullRequest
0 голосов
/ 12 января 2019

Я попытался предоставить функцию для rowfun, которая возвращает многострочный вывод той же высоты, что и ввод. , кажется, работает как положено.

% 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

Это делает код очень эффективным. В противном случае мне пришлось бы перебирать все различные значения x.idx, извлекать совпадающие строки x для каждого значения, генерировать подмножество с обращенной строкой и компилировать результаты.

Меня беспокоит только то, что я предполагаю, что порядок строк вывода анонимной функции будет сохранен, и что каждая строка будет выровнена с соответствующей строкой в ​​таблице x. Например, если idx = 7, то N-ая строка в x, для которой idx = 7, будет добавлена ​​справа к N-ой строке в выводе анонимной функции, когда она применяется к x(x.idx==7,:).

Документация rowfun не касается случаев, когда первый аргумент представляет функцию, которая возвращает многострочный вывод. На меня можно положиться только на наблюдаемое поведение. Было бы целесообразно использовать это поведение для упорядочения моего кода, или это плохая практика полагаться на такое недокументированное поведение, например, угловые случаи могут не охватываться, и TMW не обязана поддерживать текущее поведение в будущем?

Ответы [ 2 ]

0 голосов
/ 12 января 2019

Если вы хотите остаться в задокументированной зоне, вы можете использовать для этого очень удобную splitapply. Чтобы иметь дело с несколькими строками в выводе, вы можете поместить их в ячейку, а затем преобразовать в таблицу:

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'})]

Полагаю, это будет менее эффективно, но оно удерживает ваш код в документированном поведении функций без необходимости использования циклов.

0 голосов
/ 12 января 2019

Документация для rowfun, под 'GroupingVariables' гласит:

Выход B содержит по одной строке для каждой группы.

Так что, если вы получаете более одного ряда на группу, вы определенно наступаете на недокументированные воды. Будущая версия может выдать ошибку с вашим кодом.

Относительно порядка строк ввода для вашей функции: я бы посоветовал вам спросить MathWorks о порядке строк с одинаковыми переменными группировки. Одним из способов было бы перейти к нижней части страницы документации, выбрать звездный рейтинг, а затем в текстовом поле сказать, что документация не завершена, поскольку в ней не указан порядок строк, когда указана эта опция. Люди с документацией, такие как документы, являются тщательными и полными, они могут ответить на этот вопрос, заполнив документацию.

...