В этом примере показано, как извлечь подмножество большого набора данных.
Существует два аспекта подсети или выполнения запроса. Один из них выбирает подмножество переменных (столбцов) в наборе данных. Другой - это выбор подмножества наблюдений или строк.
В этом примере выбор переменных происходит в определении datastore. (Функция map может выполнить дополнительный вспомогательный выбор переменных, но это не входит в возможности этого примера). В этом примере роль функции map состоит в том, чтобы выполнить выбор наблюдений. Роль функции сокращения состоит в том, чтобы объединить подмножество записей, извлеченных каждым вызовом, в функцию map. Этот подход принимает, что набор данных может помещаться в памяти после фазы Map.
Создайте datastore с помощью airlinesmall.csv
набор данных. Этот 12-мегабайтный набор данных содержит 29 столбцов информации о рейсе для нескольких авиаперевозчиков, включая время прибытия и вылета. Этот пример использует 15 переменных из 29 переменных, доступных в данных.
ds = tabularTextDatastore('airlinesmall.csv', 'TreatAsMissing', 'NA'); ds.SelectedVariableNames = ds.VariableNames([1 2 5 9 12 13 15 16 17 ... 18 20 21 25 26 27]); ds.SelectedVariableNames
ans = 1x15 cell
Columns 1 through 4
{'Year'} {'Month'} {'DepTime'} {'UniqueCarrier'}
Columns 5 through 8
{'ActualElapsedTime'} {'CRSElapsedTime'} {'ArrDelay'} {'DepDelay'}
Columns 9 through 13
{'Origin'} {'Dest'} {'TaxiIn'} {'TaxiOut'} {'CarrierDelay'}
Columns 14 through 15
{'WeatherDelay'} {'NASDelay'}
datastore лечит 'NA'
значения как отсутствующие и заменяет отсутствующие значения на NaN
значения по умолчанию. Кроме того, SelectedVariableNames
свойство позволяет работать только с заданными интересующими переменными, которые можно проверить используя preview
.
preview(ds)
ans=8×15 table
Year Month DepTime UniqueCarrier ActualElapsedTime CRSElapsedTime ArrDelay DepDelay Origin Dest TaxiIn TaxiOut CarrierDelay WeatherDelay NASDelay
____ _____ _______ _____________ _________________ ______________ ________ ________ _______ _______ ______ _______ ____________ ____________ ________
1987 10 642 {'PS'} 53 57 8 12 {'LAX'} {'SJC'} NaN NaN NaN NaN NaN
1987 10 1021 {'PS'} 63 56 8 1 {'SJC'} {'BUR'} NaN NaN NaN NaN NaN
1987 10 2055 {'PS'} 83 82 21 20 {'SAN'} {'SMF'} NaN NaN NaN NaN NaN
1987 10 1332 {'PS'} 59 58 13 12 {'BUR'} {'SJC'} NaN NaN NaN NaN NaN
1987 10 629 {'PS'} 77 72 4 -1 {'SMF'} {'LAX'} NaN NaN NaN NaN NaN
1987 10 1446 {'PS'} 61 65 59 63 {'LAX'} {'SJC'} NaN NaN NaN NaN NaN
1987 10 928 {'PS'} 84 79 3 -2 {'SAN'} {'SFO'} NaN NaN NaN NaN NaN
1987 10 859 {'PS'} 155 143 11 -1 {'SEA'} {'LAX'} NaN NaN NaN NaN NaN
The mapreduce
функция требует функции map и функции reduce в качестве входов. mapper получает блоки данных и выводит промежуточные результаты. Редуктор считывает промежуточные результаты и дает конечный результат.
В этом примере mapper получает таблицу с переменными, описанными SelectedVariableNames
свойство в datastore. Затем картограф извлекает рейсы, которые имели высокую величину задержки после отталкивания от ворот. В частности, он определяет рейсы с длительности, превышающей в 2,5 раза длину запланированной длительности. Mapper игнорирует рейсы до 1995 года, потому что некоторые переменные, представляющие интерес для этого примера, не были собраны до этого года.
Отобразите файл функции map.
function subsettingMapper(data, ~, intermKVStore) % Select flights from 1995 and later that had exceptionally long % elapsed flight times (including both time on the tarmac and time in % the air). idx = data.Year > 1994 & (data.ActualElapsedTime - data.CRSElapsedTime)... > 1.50 * data.CRSElapsedTime; intermVal = data(idx,:); add(intermKVStore,'Null',intermVal); end
Редуктор получает подмножество наблюдений, полученное от мэппера, и просто конкатенирует их в одну таблицу. Редуктор возвращает одну клавишу (которая относительно бессмысленна) и одно значение (конкатенированная таблица).
Отобразите файл функции сокращения.
function subsettingReducer(~, intermValList, outKVStore) % get all intermediate results from the list outVal = {}; while hasnext(intermValList) outVal = [outVal; getnext(intermValList)]; end % Note that this approach assumes the concatenated intermediate values (the % subset of the whole data) fit in memory. add(outKVStore, 'Null', outVal); end
Использование mapreduce
для применения карты и сокращения функций к datastore, ds
.
result = mapreduce(ds, @subsettingMapper, @subsettingReducer);
******************************** * 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 100%
mapreduce
возвращает выход datastore, result
, с файлами в текущей папке.
Проверьте шаблоны в первых 10 переменных, которые были извлечены из набора данных. Эти переменные идентифицируют авиакомпанию, пункт назначения и аэропорты прибытия, а также некоторую базовую информацию о задержке.
r = readall(result); tbl = r.Value{1}; tbl(:,1:10)
ans=37×10 table
Year Month DepTime UniqueCarrier ActualElapsedTime CRSElapsedTime ArrDelay DepDelay Origin Dest
____ _____ _______ _____________ _________________ ______________ ________ ________ _______ _______
1995 6 1601 {'US'} 162 58 118 14 {'BWI'} {'PIT'}
1996 6 1834 {'CO'} 241 75 220 54 {'IAD'} {'EWR'}
1997 1 730 {'DL'} 110 43 137 70 {'ATL'} {'GSP'}
1997 4 1715 {'UA'} 152 57 243 148 {'IND'} {'ORD'}
1997 9 2232 {'NW'} 143 50 115 22 {'DTW'} {'CMH'}
1997 10 1419 {'CO'} 196 58 157 19 {'DFW'} {'IAH'}
1998 3 2156 {'DL'} 139 49 146 56 {'TYS'} {'ATL'}
1998 10 1803 {'NW'} 291 81 213 3 {'MSP'} {'ORD'}
2000 5 830 {'WN'} 140 55 85 0 {'DAL'} {'HOU'}
2000 8 1630 {'CO'} 357 123 244 10 {'EWR'} {'CLT'}
2002 6 1759 {'US'} 260 67 192 -1 {'LGA'} {'BOS'}
2003 3 1214 {'XE'} 214 84 124 -6 {'GPT'} {'IAH'}
2003 3 604 {'XE'} 175 60 114 -1 {'LFT'} {'IAH'}
2003 4 1556 {'MQ'} 142 52 182 92 {'PIA'} {'ORD'}
2003 5 1954 {'US'} 127 48 78 -1 {'RDU'} {'CLT'}
2003 7 1250 {'FL'} 261 95 166 0 {'ATL'} {'IAD'}
⋮
Глядя на первую запись, рейс U.S. Air покинул ворота через 14 минут после запланированного времени вылета и прибыл на 118 минут поздно. Рейс испытал задержку в 104 минуты после отталкивания от ворот, который является различием между ActualElapsedTime
и CRSElapsedTime
.
Есть одна аномальная запись. В феврале 2006 года рейс JetBlue имел время вылета 3:24 и истекшее время полета 1650 минуты, но задержку прибытия всего 415 минуты. Возможно, это ошибка при вводе данных.
В противном случае нет четких шаблонов резания, касающихся того, когда и где происходят эти исключительно задержанные рейсы. Ни одна авиакомпания, время года, время суток или один аэропорт не доминируют. Некоторые интуитивно понятные шаблоны, такие как O'Hare (ORD) в зимние месяцы, безусловно, присутствуют.
Начиная с 1995 года, данные о производительности системы авиакомпаний начали включать измерения того, какая задержка произошла на фазах такси рейса. Затем, в 2003 году, данные также стали включать определенные причины задержки.
Рассмотрим эти две переменные более подробно.
tbl(:,[1,7,8,11:end])
ans=37×8 table
Year ArrDelay DepDelay TaxiIn TaxiOut CarrierDelay WeatherDelay NASDelay
____ ________ ________ ______ _______ ____________ ____________ ________
1995 118 14 7 101 NaN NaN NaN
1996 220 54 12 180 NaN NaN NaN
1997 137 70 2 12 NaN NaN NaN
1997 243 148 4 38 NaN NaN NaN
1997 115 22 4 98 NaN NaN NaN
1997 157 19 6 95 NaN NaN NaN
1998 146 56 9 47 NaN NaN NaN
1998 213 3 11 205 NaN NaN NaN
2000 85 0 5 51 NaN NaN NaN
2000 244 10 4 273 NaN NaN NaN
2002 192 -1 6 217 NaN NaN NaN
2003 124 -6 13 131 NaN NaN NaN
2003 114 -1 8 106 NaN NaN NaN
2003 182 92 9 106 NaN NaN NaN
2003 78 -1 5 90 NaN NaN NaN
2003 166 0 11 170 0 0 166
⋮
Для этих исключительно задержанных рейсов подавляющее большинство задержек происходит во время такси, на tarmac. При этом основной причиной задержки является NASDelay. Задержки NAS удерживаются национальными авиационными властями на вылеты, направляемые в аэропорт, который, по прогнозам, не сможет обработать все запланированные прибытия на момент прибытия рейса. Программы задержки NAS, действующие в любой момент времени, размещаются в https://www.fly.faa.gov/ois/.
Предпочтительно, когда налагаются задержки NAS, обшивка на самолет просто задерживается. Такая задержка явилась бы задержкой вылета. Однако для большинства рейсов, выбранных для этого примера, задержки произошли в основном после вылета из ворот, что привело к задержке такси.
Предыдущая функция map имела критерии поднастройки, жестко подключенные в файле функции. Новая функция карты должна быть написана для любого нового запроса, такого как рейсы, вылетающие из Сан-Франциско в данный день.
Типовой mapper может быть более адаптивным, отделяя критерии подмножества от определения функции map и используя анонимную функцию, чтобы сконфигурировать mapper для каждого запроса. Этот типовой mapper использует четвертый входной параметр, который задает требуемую переменную запроса.
Отобразите типовой файл функции карты.
function subsettingMapperGeneric(data, ~, intermKVStore, subsetter) intermKey = 'Null'; intermVal = data(subsetter(data), :); add(intermKVStore,intermKey,intermVal); end
Создайте анонимную функцию, которая выполняет тот же выбор строк, который жестко закодирован в subsettingMapper
.
inFlightDelay150percent = ... @(data) data.Year > 1994 & ... (data.ActualElapsedTime-data.CRSElapsedTime) > 1.50*data.CRSElapsedTime;
Начиная с mapreduce
функция требует карты и уменьшить функции, чтобы принять ровно три входных параметра, используйте другую анонимную функцию, чтобы задать четвертый вход для mapper, subsettingMapperGeneric
. Впоследствии можно использовать эту анонимную функцию для вызова subsettingMapperGeneric
использование только трех аргументов (четвертый неявный).
configuredMapper = ... @(data, info, intermKVStore) subsettingMapperGeneric(data, info, ... intermKVStore, inFlightDelay150percent);
Использование mapreduce
применить обобщенную функцию map к входу datastore.
result2 = mapreduce(ds, configuredMapper, @subsettingReducer);
******************************** * 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 100%
mapreduce
возвращает выход datastore, result2
, с файлами в текущей папке.
Подтвердите, что типовой mapper получает тот же результат, что и с жесткой логикой подсети.
r2 = readall(result2); tbl2 = r2.Value{1}; if isequaln(tbl, tbl2) disp('Same results with the configurable mapper.') else disp('Oops, back to the drawing board.') end
Same results with the configurable mapper.
Вот карта и сокращение функций, которые mapreduce
применяется к данным.
function subsettingMapper(data, ~, intermKVStore) % Select flights from 1995 and later that had exceptionally long % elapsed flight times (including both time on the tarmac and time in % the air). idx = data.Year > 1994 & (data.ActualElapsedTime - data.CRSElapsedTime)... > 1.50 * data.CRSElapsedTime; intermVal = data(idx,:); add(intermKVStore,'Null',intermVal); end %------------------------------------------------------------------------- function subsettingReducer(~, intermValList, outKVStore) % get all intermediate results from the list outVal = {}; while hasnext(intermValList) outVal = [outVal; getnext(intermValList)]; end % Note that this approach assumes the concatenated intermediate values (the % subset of the whole data) fit in memory. add(outKVStore, 'Null', outVal); end %------------------------------------------------------------------------- function subsettingMapperGeneric(data, ~, intermKVStore, subsetter) intermKey = 'Null'; intermVal = data(subsetter(data), :); add(intermKVStore,intermKey,intermVal); end %-------------------------------------------------------------------------
mapreduce
| tabularTextDatastore