我在Matlab中有一个矩阵A:
A = [176 5406 1 4 7903;
155 5406 1 5 7903;
122 5407 0 4 7903;
140 5407 0 5 7904;
130 5407 0 3 7904];
仅供参考 - 第二列是用户ID,第四列是时间。因此5406
是一个用户,5407
是另一个用户。这两个用户都有一些信息存储在我有兴趣访问的第一列和第四列中。
基本上我想做的是:
对于每个用户,在第一列中取其值的中位数。我编写的代码(如下)适用于此。
如果有两个相等的"时间"第5列中的值为每个用户,然后我想平均第4列中的值。因此,对于用户5406
,时间值都是7903
,我想要第4列中的值的平均值 - 即4
和5
的平均值最终得到一个值(4.5
)。
但是例如对于下一个用户5407
,我将有两个最终值 - 一个是5和3的平均值(因为7904
重复),一个将是4(因为{{ 1}}不重复)。
我对如何做到这一点感到有点困惑,我知道需要某种7903
声明,但我已经被困在它上多年了。有人可以帮忙吗?
由于
第一部分的代码:
if
答案 0 :(得分:1)
您可以为每个用户的时间值(在循环内)运行unique
并执行类似的子循环以收集该用户的唯一时间戳的平均值。
但在这里,我觉得使用accumarray
比较整洁。在下面的第一个示例中,我稍微修改了您的代码。
% Get unique
[user, ~, userIdx] = unique(A(:,2));
nUser = numel(user);
% Allocate container for result
med = zeros(nUser,1);
men = cell(nUser,1); % <-- Need a cell since length of result could vary
for i = 1:nUser
% Median of col #1
med(i) = median(A(userIdx == i, 1));
% Mean of col #4 for unique times
[~, ~, timeIdx] = unique(A(userIdx == i, 5));
men{i} = accumarray(timeIdx, A(userIdx == i, 4), [], @mean);
end
结果:
>> med =
165.5
130
>> celldisp(men)
men{1} =
4.5
men{2} =
4
4
要进一步挤压它,您可以为整个A
花费唯一的时间,并使用accumarray
进行两者
[~, ~, userIdx] = unique(A(:,2));
[~, ~, timeIdx] = unique(A(:,5));
med = accumarray(userIdx, A(:,1), [], @median);
men = accumarray([userIdx timeIdx], A(:,4), [], @mean, NaN);
这使得men
不是一个单元格而是一个矩阵。因此必须填充空格(这里我选择NaN
,因为0可能是@mean
的结果)。
men =
4.5 NaN
4 4
如果您希望它作为没有NaN
的单元格,您可以循环遍历行并选择非NaN值,或者仅将men
计算放在循环中,或者以任何其他方式放置...
如果您确定A
的第4列不包含任何负数或零数(平均值不应该冒为0),您可以将men
的结果收集为稀疏矩阵代替
men = accumarray([userIdx timeIdx], A(:,4), [], @mean, 0, true);
men =
(1,1) 4.5
(2,1) 4
(2,2) 4
答案 1 :(得分:0)
我在不使用任何循环的情况下为您的任务提供了另一种解决方案:
中位值。
u=unique(A(:,2));
umedians = arrayfun( @(x) median (A( A(:,2)==x, 1)), u);
说明:
首先找到所有唯一身份用户然后使用arrayfun
查找当前用户的所有数据,并为每个用户计算median
。
第4列的平均值。
这项任务有点困难。我们可以这样:
temp = arrayfun( @(x) unique(A ( A(:,2)==x,5 )), u, 'UniformOutput',false);
result = cellfun( @(y,z) arrayfun( @(x) mean( A( A(:,2) == u(z) & A(:,5) == x ,4) ), ...
y, 'UniformOutput',false), temp , num2cell( [1:size(u,1)]'), 'UniformOutput',false)
说明:首先让我们为每个用户找到所有唯一的时间。将其保存到单元格数组temp
。现在我们需要每个单元格找到相同的时间并计算平均值。因此,我们可以使用cellfun
为temp
的每个单元格创建它,并使用arrayfun
来计算mean
。
希望它有所帮助!