Каков наиболее подходящий для MATLAB способ гистограммы отсортированного массива ячеек?

Предположим, я запускаю 7/11, и следующий массив ячеек 100x3, отсортированный по первому столбцу, времени, является моими записями о продажах.

12:32:01 customer1 12
12:32:02 customer2 13
12:32:04 customer6 4
12:32:06 customer8 6
12:32:07 customer1 9
12:32:07 customer1 6
12:32:12 customer2 1
...

Как вы заметили, каждый покупатель может совершать покупки несколько раз. например клиент 1 фактически сделал три разных платежа.

Теперь я хочу вычислить средний платеж каждого клиента. например. давайте предположим, что клиент 1 сделал только 3 платежа, как показано выше. Тогда его средний платеж составит (12+9+6)/3=9.

Я, конечно, могу написать цикл for для просмотра всех записей и отслеживания каждого клиента. Однако я чувствую, что это не так, как это должно быть сделано с MATLAB.

Итак, каков наиболее подходящий для MATLAB способ выполнения задачи?


person Sibbs Gambling    schedule 28.02.2014    source источник
comment
Извините, что снова беспокою вас, но мой ответ сработал здесь?   -  person chappjc    schedule 06.03.2014
comment
@chappjc Мне очень жаль, что я забыл отметить это как ответ! Виноват! Большое спасибо за проверку!   -  person Sibbs Gambling    schedule 11.03.2014


Ответы (2)


Начните с unique, чтобы получить целочисленный "ключ" для каждого клиента, затем передать это в accumarray с дескриптором функции @mean:

data = {'12:32:01','customer1',12; '12:32:02','customer2',13;...
        '12:32:04','customer6',4; '12:32:06','customer8',6;...
        '12:32:07','customer1',9; '12:32:07','customer1',6;...
        '12:32:12','customer2',1};
[customers,~,ic] = unique(data(:,2));
avePayment = accumarray(ic,[data{:,3}],[],@mean);

Затем соберите выходы:

>> custAvgTab = [customers num2cell(avePayment)]

custAvgTab = 

    'customer1'    [9]
    'customer2'    [7]
    'customer6'    [4]
    'customer8'    [6]

ИМХО, это довольно похоже на MATLAB и на самом деле удивительно интуитивно понятно.

ПРИМЕЧАНИЕ. Я заменил cell2mat(data(:,3)) на [data{:,3}], так как считаю, что по возможности лучше использовать встроенные операции MATLAB.

ПРИМЕЧАНИЕ 2. Для больших данных sprintfc('%d',avePayment) может быть быстрее, чем num2cell(avePayment).

person chappjc    schedule 28.02.2014

Если ваш массив ячеек организован, как показано ниже, вы можете сделать следующее:

    dataC = { ...
        {'12:32:01', 'customer1', 12}, ...
        {'12:32:02', 'customer2', 13}, ...
        {'12:32:04', 'customer6', 4}, ...
        {'12:32:06', 'customer8', 6}, ...
        {'12:32:07', 'customer1', 9}, ...
        {'12:32:07', 'customer1', 6}, ...
        {'12:32:12', 'customer2', 1}, ...
    };



   % get unique costumer names
   uniqueCostumers = ...
       unique(cellfun(@(c) c{2},  dataC, 'UniformOutput', false));


   for i = 1:numel(uniqueCostumers)
       customer = uniqueCostumers{i};

       % payments for a given customer, including zero payments
       paymetsC = cellfun(@(c) strcmp(c{2}, customer) * c{3},  dataC, 'UniformOutput', false);

       %convert to vector
       paymetsV = [paymetsC{:}];

       % calculate mean manually
       meanValue = mean(paymetsV(paymetsV ~= 0));

       fprintf(1, 'Mean for %s is %.2f\n', customer, meanValue);
   end

Это приводит к:

Mean for customer1 is 9.00
Mean for customer2 is 7.00
Mean for customer6 is 4.00
Mean for customer8 is 6.00
person Marcin    schedule 28.02.2014