Этот пример показывает, как вычислить итоговую статистику, организованную группой, использующей mapreduce
. Это демонстрирует использование анонимной функции, чтобы передать дополнительный параметр группировки параметризованной функции карты. Эта параметризация позволяет вам быстро повторно вычислять статистику с помощью различной группирующей переменной.
Создайте datastore с помощью набора данных airlinesmall.csv
. Этот набор данных на 12 мегабайтов содержит 29 столбцов информации о рейсе для нескольких поставщиков услуг авиакомпании, включая прибытие и время отправления. В данном примере выберите Month
, UniqueCarrier
(ID поставщика услуг авиакомпании), и ArrDelay
(задержка прибытия рейса) как переменные интереса.
ds = datastore('airlinesmall.csv', 'TreatAsMissing', 'NA'); ds.SelectedVariableNames = {'Month', 'UniqueCarrier', 'ArrDelay'};
Datastore обрабатывает значения 'NA'
как пропавших без вести и заменяет отсутствующие значения на значения NaN
по умолчанию. Кроме того, свойство SelectedVariableNames
позволяет вам работать только с выбранными переменными интереса, который можно проверить использование preview
.
preview(ds)
ans = 8x3 table Month UniqueCarrier ArrDelay _____ _____________ ________ 10 'PS' 8 10 'PS' 8 10 'PS' 21 10 'PS' 13 10 'PS' 4 10 'PS' 59 10 'PS' 3 10 'PS' 11
Функция mapreduce
требует функции карты и уменьшать функции как входные параметры. Картопостроитель получает фрагменты данных и выходных промежуточных результатов. Редуктор читает, промежуточное звено заканчивается и приводит к конечному результату.
В этом примере картопостроитель вычисляет сгруппированную статистику для каждого фрагмента данных и хранит статистику как промежуточные пары "ключ-значение". Каждая промежуточная пара "ключ-значение" имеет ключ для уровня группы и массива ячеек значений с соответствующей статистикой.
Эта функция карты принимает четыре входных параметра, тогда как функция mapreduce
требует, чтобы функция карты приняла точно три входных параметра. Вызов mapreduce
(ниже) показов, как передать в этом дополнительном параметре.
Отобразите файл функции карты.
function statsByGroupMapper(data, ~, intermKVStore, groupVarName) % Mapper function for the StatisticsByGroupMapReduceExample. % Copyright 2014 The MathWorks, Inc. % Data is a n-by-3 table. Remove missing values first delays = data.ArrDelay; groups = data.(groupVarName); notNaN =~isnan(delays); groups = groups(notNaN); delays = delays(notNaN); % find the unique group levels in this chunk [intermKeys,~,idx] = unique(groups, 'stable'); % group delays by idx and apply @grpstatsfun function to each group intermVals = accumarray(idx,delays,size(intermKeys),@grpstatsfun); addmulti(intermKVStore,intermKeys,intermVals); function out = grpstatsfun(x) n = length(x); % count m = sum(x)/n; % mean v = sum((x-m).^2)/n; % variance s = sum((x-m).^3)/n; % skewness without normalization k = sum((x-m).^4)/n; % kurtosis without normalization out = {[n, m, v, s, k]};
После фазы Map mapreduce
группирует промежуточные пары "ключ-значение" уникальным ключом (в этом случае, ID поставщика услуг авиакомпании), таким образом, каждый вызов уменьшать функции работает над значениями, сопоставленными с одной авиакомпанией. Редуктор получает список промежуточной статистики для авиакомпании, заданной входным ключом (intermKey
), и комбинирует статистику в отдельные векторы: n
, m
, v
, s
и k
. Затем редуктор использует эти векторы, чтобы вычислить количество, среднее значение, отклонение, скошенность и эксцесс для одной авиакомпании. Итоговый ключ является кодом поставщика услуг авиакомпании, и присваиваемые значения хранятся в структуре с пятью полями.
Отобразите уменьшать файл функции.
function statsByGroupReducer(intermKey, intermValIter, outKVStore) % Reducer function for the StatisticsByGroupMapReduceExample. % Copyright 2014 The MathWorks, Inc. n = []; m = []; v = []; s = []; k = []; % get all sets of intermediate statistics while hasnext(intermValIter) value = getnext(intermValIter); n = [n; value(1)]; m = [m; value(2)]; v = [v; value(3)]; s = [s; value(4)]; k = [k; value(5)]; end % Note that this approach assumes the concatenated intermediate values fit % in memory. Refer to the reducer function, covarianceReducer, of the % CovarianceMapReduceExample for an alternative pairwise reduction approach % combine the intermediate results count = sum(n); meanVal = sum(n.*m)/count; d = m - meanVal; variance = (sum(n.*v) + sum(n.*d.^2))/count; skewnessVal = (sum(n.*s) + sum(n.*d.*(3*v + d.^2)))./(count*variance^(1.5)); kurtosisVal = (sum(n.*k) + sum(n.*d.*(4*s + 6.*v.*d +d.^3)))./(count*variance^2); outValue = struct('Count',count, 'Mean',meanVal, 'Variance',variance,... 'Skewness',skewnessVal, 'Kurtosis',kurtosisVal); % add results to the output datastore add(outKVStore,intermKey,outValue);
Используйте mapreduce
, чтобы применить map и reduce функции к datastore, ds
. Поскольку параметризованная функция карты принимает четыре входных параметров, используйте анонимную функцию, чтобы передать в идентификаторах поставщика услуг авиакомпании как четвертый вход.
outds1 = mapreduce(ds, ... @(data,info,kvs)statsByGroupMapper(data,info,kvs,'UniqueCarrier'), ... @statsByGroupReducer);
******************************** * MAPREDUCE PROGRESS * ******************************** Map 0% Reduce 0% Map 16% Reduce 0% Map 32% Reduce 0% Map 48% Reduce 0% Map 65% Reduce 0% Map 81% Reduce 0% Map 97% Reduce 0% Map 100% Reduce 0% Map 100% Reduce 10% Map 100% Reduce 21% Map 100% Reduce 31% Map 100% Reduce 41% Map 100% Reduce 52% Map 100% Reduce 62% Map 100% Reduce 72% Map 100% Reduce 83% Map 100% Reduce 93% Map 100% Reduce 100%
mapreduce
возвращает datastore, outds1
, с файлами в текущей папке.
Считайте конечные результаты из выходного datastore.
r1 = readall(outds1)
r1 = 29x2 table Key Value ________ ____________ 'PS' [1x1 struct] 'TW' [1x1 struct] 'UA' [1x1 struct] 'WN' [1x1 struct] 'EA' [1x1 struct] 'HP' [1x1 struct] 'NW' [1x1 struct] 'PA (1)' [1x1 struct] 'PI' [1x1 struct] 'CO' [1x1 struct] 'DL' [1x1 struct] 'AA' [1x1 struct] 'US' [1x1 struct] 'AS' [1x1 struct] 'ML (1)' [1x1 struct] 'AQ' [1x1 struct] 'MQ' [1x1 struct] 'OO' [1x1 struct] 'XE' [1x1 struct] 'TZ' [1x1 struct] 'EV' [1x1 struct] 'FL' [1x1 struct] 'B6' [1x1 struct] 'DH' [1x1 struct] 'HA' [1x1 struct] 'OH' [1x1 struct] 'F9' [1x1 struct] 'YV' [1x1 struct] '9E' [1x1 struct]
Чтобы организовать результаты лучше, преобразуйте структуру, содержащую статистику в таблицу, и используйте идентификаторы поставщика услуг в качестве имен строки. mapreduce
возвращает пары "ключ-значение" в том же порядке, как они были добавлены уменьшать функцией, так отсортируйте таблицу по ID поставщика услуг.
statsByCarrier = struct2table(cell2mat(r1.Value), 'RowNames', r1.Key); statsByCarrier = sortrows(statsByCarrier, 'RowNames')
statsByCarrier = 29x5 table Count Mean Variance Skewness Kurtosis _____ _______ ________ ________ ________ 9E 507 5.3669 1889.5 6.2676 61.706 AA 14578 6.9598 1123 6.0321 93.085 AQ 153 1.0065 230.02 3.9905 28.383 AS 2826 8.0771 717 3.6547 24.083 B6 793 11.936 2087.4 4.0072 27.45 CO 7999 7.048 1053.8 4.6601 41.038 DH 673 7.575 1491.7 2.9929 15.461 DL 16284 7.4971 697.48 4.4746 41.115 EA 875 8.2434 1221.3 5.2955 43.518 EV 1655 10.028 1325.4 2.9347 14.878 F9 332 8.4849 1138.6 4.2983 30.742 FL 1248 9.5144 1360.4 3.6277 21.866 HA 271 -1.5387 323.27 8.4245 109.63 HP 3597 7.5897 744.51 5.2534 50.004 ML (1) 69 0.15942 169.32 2.8354 16.559 MQ 3805 8.8591 1530.5 7.054 105.51 NW 10097 5.4265 977.64 8.616 172.87 OH 1414 7.7617 1224 3.57 24.52 OO 3010 5.8618 1010.4 4.4263 32.783 PA (1) 313 5.3738 692.19 3.2061 20.747 PI 861 11.252 1121.1 14.751 315.59 PS 82 5.3902 454.51 2.9682 14.383 TW 3718 7.411 830.76 4.139 30.67 TZ 215 1.907 814.63 2.8269 13.758 UA 12955 8.3939 1046.6 3.9742 28.187 US 13666 6.8027 760.83 4.6905 47.975 WN 15749 5.4581 562.49 4.0439 30.403 XE 2294 8.8082 1410.1 3.7114 23.235 YV 827 12.376 2192.6 3.9315 26.446
Использование анонимной функции, чтобы передать в группирующей переменной позволяет вам быстро повторно вычислять статистику с различной группировкой.
В данном примере повторно вычислите статистику и сгруппируйте результаты Month
, вместо идентификаторами поставщика услуг, путем простой передачи переменной Month
в анонимную функцию.
outds2 = mapreduce(ds, ... @(data,info,kvs)statsByGroupMapper(data,info,kvs,'Month'), ... @statsByGroupReducer);
******************************** * MAPREDUCE PROGRESS * ******************************** Map 0% Reduce 0% Map 16% Reduce 0% Map 32% Reduce 0% Map 48% Reduce 0% Map 65% Reduce 0% Map 81% Reduce 0% Map 97% Reduce 0% Map 100% Reduce 0% Map 100% Reduce 17% Map 100% Reduce 33% Map 100% Reduce 50% Map 100% Reduce 67% Map 100% Reduce 83% Map 100% Reduce 100%
Считайте конечные результаты и организуйте их в таблицу.
r2 = readall(outds2); r2 = sortrows(r2,'Key'); statsByMonth = struct2table(cell2mat(r2.Value)); mon = {'Jan','Feb','Mar','Apr','May','Jun', ... 'Jul','Aug','Sep','Oct','Nov','Dec'}; statsByMonth.Properties.RowNames = mon
statsByMonth = 12x5 table Count Mean Variance Skewness Kurtosis _____ ______ ________ ________ ________ Jan 9870 8.5954 973.69 4.1142 35.152 Feb 9160 7.3275 911.14 4.7241 45.03 Mar 10219 7.5536 976.34 5.1678 63.155 Apr 9949 6.0081 1077.4 8.9506 170.52 May 10180 5.2949 737.09 4.0535 30.069 Jun 10045 10.264 1266.1 4.8777 43.5 Jul 10340 8.7797 1069.7 5.1428 64.896 Aug 10470 7.4522 908.64 4.1959 29.66 Sep 9691 3.6308 664.22 4.6573 38.964 Oct 10590 4.6059 684.94 5.6407 74.805 Nov 10071 5.2835 808.65 8.0297 186.68 Dec 10281 10.571 1087.6 3.8564 28.823