Matlab 通过使用varfun进行分组,索引中的最大值

Matlab 通过使用varfun进行分组,索引中的最大值,matlab,sorting,matlab-table,Matlab,Sorting,Matlab Table,我有一张有ID和日期的桌子。我想检索每个Id的最大日期索引 我最初的做法是: varfun(@max,table,'Grouping Variables','Id','InputVariables','Date') 这显然给了我日期而不是索引。 我注意到,如果指定,max函数将同时返回maxvalue和maxindex: [max_val,max_idx]=max(值) 如何使用max来检索max_idx来定义匿名函数?然后我会在var_fun中使用它来获得结果 我不希望将max()上的覆盖函数

我有一张有ID和日期的桌子。我想检索每个Id的最大日期索引

我最初的做法是: varfun(@max,table,'Grouping Variables','Id','InputVariables','Date')

这显然给了我日期而不是索引。 我注意到,如果指定,max函数将同时返回maxvalue和maxindex: [max_val,max_idx]=max(值)

如何使用max来检索max_idx来定义匿名函数?然后我会在var_fun中使用它来获得结果

我不希望将max()上的覆盖函数(与anon func相反)声明为: 1.我正在使用脚本,不希望创建另一个函数文件 2.我不愿意将当前脚本更改为函数


谢谢大家,

我不认为
varfun
是正确的方法,因为

varfun(func,A)
将函数
func
分别应用于 表格
A

只有当您想将其应用于多个列时,这才有意义

简单方法: 只需使用循环方法:首先使用
unique
找到不同的ID,然后为每个ID找到最长日期的索引。(这假设您的日期是数字格式,可以使用
max
直接进行比较) 我确实将变量
重命名为
t
,否则我们将覆盖内置函数

uniqueIds = unique(t.Id);
for i = 1:numel(uniqueIds)
    equalsCurrentId = t.Id==uniqueIds(i); 
    globalIdxs = find(equalsCurrentId);
    [~, localIdxsOfMax] = max(t.Date(equalsCurrentId));
    maxIdxs{i} = globalIdxs(localIdxsOfMax);
end
正如您提到的,
Id
实际上是字符串而不是数字,您必须更改行:
equalsCurrentId=t.Id==uniqueid(i)

 equalsCurrentId = strcmp(t.Id, uniqueIds{i});
使用accumarray进近: 如果您喜欢更紧凑的样式,您可以使用受启发的此解决方案,该解决方案适用于数字和字符串ID:

[uniqueIds, ~, global2Unique] = unique(t.Id);
maxDateIdxsOfIdxSubset = @(I) {I(nth_output(2, @max, t.Date(I)))};
maxIdxs = accumarray(global2Unique, 1:length(t.Id), [], maxDateIdxsOfIdxSubset);
这使用gnovice的第n个输出

用法: 上述两种解决方案都将产生:一个向量
uniqueid
,带有相应的
单元格
数组
maxIdxs
,其方式是
maxIdxs{i}
uniqueid(i)
的最大日期的索引。 如果您只需要一个索引,即使有多个条目达到最大值,也可以使用以下方法去除不需要的数据:

maxIdxs = cellfun(@(X) X(1), maxIdxs);

我不认为
varfun
是正确的方法,因为

varfun(func,A)
将函数
func
分别应用于 表格
A

只有当您想将其应用于多个列时,这才有意义

简单方法: 只需使用循环方法:首先使用
unique
找到不同的ID,然后为每个ID找到最长日期的索引。(这假设您的日期是数字格式,可以使用
max
直接进行比较) 我确实将变量
重命名为
t
,否则我们将覆盖内置函数

uniqueIds = unique(t.Id);
for i = 1:numel(uniqueIds)
    equalsCurrentId = t.Id==uniqueIds(i); 
    globalIdxs = find(equalsCurrentId);
    [~, localIdxsOfMax] = max(t.Date(equalsCurrentId));
    maxIdxs{i} = globalIdxs(localIdxsOfMax);
end
正如您提到的,
Id
实际上是字符串而不是数字,您必须更改行:
equalsCurrentId=t.Id==uniqueid(i)

 equalsCurrentId = strcmp(t.Id, uniqueIds{i});
使用accumarray进近: 如果您喜欢更紧凑的样式,您可以使用受启发的此解决方案,该解决方案适用于数字和字符串ID:

[uniqueIds, ~, global2Unique] = unique(t.Id);
maxDateIdxsOfIdxSubset = @(I) {I(nth_output(2, @max, t.Date(I)))};
maxIdxs = accumarray(global2Unique, 1:length(t.Id), [], maxDateIdxsOfIdxSubset);
这使用gnovice的第n个输出

用法: 上述两种解决方案都将产生:一个向量
uniqueid
,带有相应的
单元格
数组
maxIdxs
,其方式是
maxIdxs{i}
uniqueid(i)
的最大日期的索引。 如果您只需要一个索引,即使有多个条目达到最大值,也可以使用以下方法去除不需要的数据:

maxIdxs = cellfun(@(X) X(1), maxIdxs);

我假设你的ID是正整数,日期是数字

如果您想要每个Id的最长日期,那么使用
max
函数将非常适合。在下文中,我将使用
f
表示传递给
accumarray
的通用函数

事实上,您想要的是最大值的索引,这使得它有点棘手(而且更有趣!)。问题是,与给定Id对应的日期被传递到
f
,而不引用其原始索引。因此,基于
max
f
是没有帮助的。但您可以将索引作为日期的假想部分“通过”
accumarray

因此:如果您希望每个Id只有一个最大化索引(即使有多个):

result = accumarray(t.Id,...  %// col vector of Id's
    t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
    [], ... %// default size for output
    @(x) imag(x(find(real(x)==max(real(x))),1))); %// function f
result = accumarray(t.Id,...  %// col vector of Id's
    t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
    [], ... %// default size for output
    @(x) {imag(x(find(real(x)==max(real(x)))))}); %// function f
注意这里的函数
f
最大化实部,然后提取包含原始索引的虚部

或者,如果希望每个Id的所有索引最大化:

result = accumarray(t.Id,...  %// col vector of Id's
    t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
    [], ... %// default size for output
    @(x) imag(x(find(real(x)==max(real(x))),1))); %// function f
result = accumarray(t.Id,...  %// col vector of Id's
    t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
    [], ... %// default size for output
    @(x) {imag(x(find(real(x)==max(real(x)))))}); %// function f
如果您的ID是字符串:使用的第三个输出将其转换为数字标签,然后按上述步骤进行操作:

[~, ~, NumId] = unique(t.Id);
然后要么

result = accumarray(NumId,...  %// col vector of Id's
    t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
    [], ... %// default size for output
    @(x) imag(x(find(real(x)==max(real(x))),1))); % function f


我假设你的ID是正整数,日期是数字

如果您想要每个Id的最长日期,那么使用
max
函数将非常适合。在下文中,我将使用
f
表示传递给
accumarray
的通用函数

事实上,您想要的是最大值的索引,这使得它有点棘手(而且更有趣!)。问题是,与给定Id对应的日期被传递到
f
,而不引用其原始索引。因此,基于
max
f
是没有帮助的。但您可以将索引作为日期的假想部分“通过”
accumarray

因此:如果您希望每个Id只有一个最大化索引(即使有多个):

result = accumarray(t.Id,...  %// col vector of Id's
    t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
    [], ... %// default size for output
    @(x) imag(x(find(real(x)==max(real(x))),1))); %// function f
result = accumarray(t.Id,...  %// col vector of Id's
    t.Date+1j*(1:size(t,1)).', ... %'// col vector of Dates (real) and indices (imag)
    [], ... %// default size for output
    @(x) {imag(x(find(real(x)==max(real(x)))))}); %// function f
请注意,函数
f