我有一张包含Ids和Dates的表格。我想检索每个Id的最大日期索引。
我最初的做法是这样的: varfun(@ max,table,'Grouping Variables','Id','InputVariables','Date');
这显然给了我日期而不是索引。 我注意到max函数将在指定时返回maxvalue和maxindex: [max_val,max_idx] = max(values);
如何使用max定义匿名函数来检索max_idx?然后我会在var_fun中使用它来获取我的结果。
我不想在max()上声明一个封面函数(而不是anon func): 我正在使用脚本而不想创建另一个函数文件 2.我不愿意将当前脚本更改为函数
感谢一百万人,
答案 0 :(得分:3)
我假设你的 ID是正整数而你的日期是数字。
如果您想要每个ID的最大日期,那么accumarray
具有max
功能将是一个完美的案例。在下文中,我将使用f
来表示传递给accumarray
的泛型函数。
你想要索引的最大值使它变得有点棘手(而且更有趣!)。问题是对应于给定Id的日期将传递给f
,而不会引用其原始索引。因此,基于f
的{{1}}无法提供帮助。但您可以将索引“通过”max
作为日期的虚部。
所以:如果你想要每个Id只有一个最大化索引(即使有几个):
accumarray
请注意,此处的函数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
最大化 real 部分,然后提取虚构部分,其中包含原始索引。
或者,如果您希望所有最大化每个Id的索引:
f
如果您的 ID是字符串:使用unique
的第三个输出将它们转换为数字标签,然后按上述步骤操作:
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
然后
[~, ~, 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
答案 1 :(得分:2)
我认为varfun
是正确的方法,因为
varfun(func,A)
将函数func
分别应用于每个变量 表A
。
如果您想将其应用于多个列,这只会有意义。
简单地使用循环方法:首先使用unique
查找不同的ID,然后为每个ID找到最大日期的索引。 (这假设您的日期采用数字格式,可以使用max
直接比较。)
我确实将变量table
重命名为t
,否则我们将覆盖内置函数table
。
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
正如您所提到的,Ids
实际上是字符串而不是数字,您必须更改行:equalsCurrentId = t.Id==uniqueIds(i);
到
equalsCurrentId = strcmp(t.Id, uniqueIds{i});
accumarray
的方法:如果您更喜欢更紧凑的风格,可以使用受Luis Mendo's answer启发的此解决方案,该解决方案适用于数字和字符串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 的nth_output
great answer。
以上两种解决方案都会产生:带有对应uniqueIds
- 数组cell
的向量maxIdxs
,其中maxIdxs{i}
是uniqueIds(i)
的最大日期的索引{1}}。
如果您只需要一个索引,即使有多个条目达到最大值,请使用以下内容删除不需要的数据:
maxIdxs = cellfun(@(X) X(1), maxIdxs);