Matlab 通过使用varfun进行分组,索引中的最大值
我有一张有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.我不愿意将当前脚本更改为函数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()上的覆盖函数
谢谢大家,我不认为
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