Предварительная обработка и Исследование Данных С меткой времени Используя расписание

В этом примере показано, как анализировать велосипедные шаблоны трафика из данных о датчике с помощью timetable контейнер данных, чтобы организовать и предварительно обработать данные, к которым добавляют метку времени. Данные прибывают из датчиков на Броудвей-Стрит в Кембридже, MA. Город Кембриджа предоставляет открытый доступ полному набору данных в Кембридже Открытый сайт Данных.

В этом примере показано, как выполнить разнообразие очистки данных, порчи и предварительной обработки задач, таких как удаление отсутствующих значений и синхронизация данных с меткой времени с различными тактами. Кроме того, исследование данных подсвечено включая визуализацию и сгруппированные вычисления с помощью timetable контейнер данных к:

  • Исследуйте ежедневный велосипедный трафик

  • Сравните велосипедный трафик с локальными погодными условиями

  • Анализируйте велосипедный трафик в различные дни недели и времени суток

Импортирование велосипедных данных трафика в расписание

Импортируйте выборку велосипедных данных о трафике из разделенного от запятой текстового файла. readtable функция возвращает данные в таблице. Отобразите первые восемь строк с помощью head функция.

bikeTbl = readtable('BicycleCounts.csv');
head(bikeTbl)
ans=8×5 table
         Timestamp              Day         Total    Westbound    Eastbound
    ___________________    _____________    _____    _________    _________

    2015-06-24 00:00:00    {'Wednesday'}      13         9             4   
    2015-06-24 01:00:00    {'Wednesday'}       3         3             0   
    2015-06-24 02:00:00    {'Wednesday'}       1         1             0   
    2015-06-24 03:00:00    {'Wednesday'}       1         1             0   
    2015-06-24 04:00:00    {'Wednesday'}       1         1             0   
    2015-06-24 05:00:00    {'Wednesday'}       7         3             4   
    2015-06-24 06:00:00    {'Wednesday'}      36         6            30   
    2015-06-24 07:00:00    {'Wednesday'}     141        13           128   

Данные имеют метки времени, таким образом, удобно использовать расписание, чтобы сохранить и анализировать данные. Расписание похоже на таблицу, но включает метки времени, которые сопоставлены со строками данных. Метки времени, или времена строки, представлены datetime или duration значения. datetime и duration рекомендуемые типы данных для представления моментов времени или прошедшие времена, соответственно.

Преобразуйте bikeTbl в расписание с помощью table2timetable функция. Необходимо использовать функцию преобразования потому что readtable возвращает таблицу. table2timetable преобразует первый datetime или duration переменная в таблице во времена строки расписания. Времена строки являются метаданными, которые помечают строки. Однако, когда вы отображаете расписание, времена строки и переменные расписания отображены подобным способом. Обратите внимание на то, что таблица имеет пять переменных, тогда как расписание имеет четыре.

bikeData = table2timetable(bikeTbl);
head(bikeData)
ans=8×4 timetable
         Timestamp              Day         Total    Westbound    Eastbound
    ___________________    _____________    _____    _________    _________

    2015-06-24 00:00:00    {'Wednesday'}      13         9             4   
    2015-06-24 01:00:00    {'Wednesday'}       3         3             0   
    2015-06-24 02:00:00    {'Wednesday'}       1         1             0   
    2015-06-24 03:00:00    {'Wednesday'}       1         1             0   
    2015-06-24 04:00:00    {'Wednesday'}       1         1             0   
    2015-06-24 05:00:00    {'Wednesday'}       7         3             4   
    2015-06-24 06:00:00    {'Wednesday'}      36         6            30   
    2015-06-24 07:00:00    {'Wednesday'}     141        13           128   

whos bikeTbl bikeData
  Name             Size              Bytes  Class        Attributes

  bikeData      9387x4             1412426  timetable              
  bikeTbl       9387x5             1487736  table                  

Времена доступа и данные

Преобразуйте Day переменная к категориальному. Тип категориальных данных спроектирован для данных, которые состоят из конечного множества дискретных значений, таких как имена дней недели. Перечислите категории, таким образом, они отображаются в дневном порядке. Используйте индексирование точки для переменных доступа по наименованию.

bikeData.Day = categorical(bikeData.Day,{'Sunday','Monday','Tuesday',...
                       'Wednesday','Thursday','Friday','Saturday'});  

В расписании времена обработаны отдельно от переменных данных. Доступ к Properties из расписания, чтобы показать, что времена строки являются первой размерностью расписания и переменными, второе измерение. DimensionNames свойство показывает имена этих двух размерностей, в то время как VariableNames свойство показывает имена переменных вдоль второго измерения.

bikeData.Properties
ans = 
  TimetableProperties with properties:

             Description: ''
                UserData: []
          DimensionNames: {'Timestamp'  'Variables'}
           VariableNames: {'Day'  'Total'  'Westbound'  'Eastbound'}
    VariableDescriptions: {}
           VariableUnits: {}
      VariableContinuity: []
                RowTimes: [9387x1 datetime]
               StartTime: 2015-06-24 00:00:00
              SampleRate: NaN
                TimeStep: NaN
        CustomProperties: No custom properties are set.
      Use addprop and rmprop to modify CustomProperties.

По умолчанию, table2timetable присвоенный Timestamp как первое имя размерности, когда это преобразовало таблицу в расписание, поскольку это было именем переменной из исходной таблицы. Можно поменять имена размерностей и другие метаданные расписания, через Properties.

Поменяйте имена размерностей к Time и Data.

bikeData.Properties.DimensionNames = {'Time' 'Data'};
bikeData.Properties
ans = 
  TimetableProperties with properties:

             Description: ''
                UserData: []
          DimensionNames: {'Time'  'Data'}
           VariableNames: {'Day'  'Total'  'Westbound'  'Eastbound'}
    VariableDescriptions: {}
           VariableUnits: {}
      VariableContinuity: []
                RowTimes: [9387x1 datetime]
               StartTime: 2015-06-24 00:00:00
              SampleRate: NaN
                TimeStep: NaN
        CustomProperties: No custom properties are set.
      Use addprop and rmprop to modify CustomProperties.

Отобразите первые восемь строк расписания.

head(bikeData)
ans=8×4 timetable
           Time               Day       Total    Westbound    Eastbound
    ___________________    _________    _____    _________    _________

    2015-06-24 00:00:00    Wednesday      13         9             4   
    2015-06-24 01:00:00    Wednesday       3         3             0   
    2015-06-24 02:00:00    Wednesday       1         1             0   
    2015-06-24 03:00:00    Wednesday       1         1             0   
    2015-06-24 04:00:00    Wednesday       1         1             0   
    2015-06-24 05:00:00    Wednesday       7         3             4   
    2015-06-24 06:00:00    Wednesday      36         6            30   
    2015-06-24 07:00:00    Wednesday     141        13           128   

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

elapsedTime = max(bikeData.Time) - min(bikeData.Time)
elapsedTime = duration
   9383:30:00

elapsedTime.Format = 'd'
elapsedTime = duration
   390.98 days

Исследовать типичный велосипед рассчитывает на данный день, вычислите средние значения для общего количества велосипедов и числа, переместившись движущийся на запад и идущий на восток.

Возвратите числовые данные как матрицу путем индексации в содержимое bikeData использование фигурных скобок. Отобразите первые восемь строк. Используйте стандартное табличное индексирование, чтобы получить доступ к нескольким переменным.

counts = bikeData{:,2:end};
counts(1:8,:)
ans = 8×3

    13     9     4
     3     3     0
     1     1     0
     1     1     0
     1     1     0
     7     3     4
    36     6    30
   141    13   128

Поскольку среднее значение подходит только для числовых данных, можно использовать vartype функционируйте, чтобы выбрать числовые переменные. vartype может быть более удобным, чем ручная индексация в таблицу или расписание, чтобы выбрать переменные. Вычислите средние значения и не используйте NaN значения.

counts = bikeData{:,vartype('numeric')};
mean(counts,'omitnan')
ans = 1×3

   49.8860   24.2002   25.6857

Выбор Data по дате и время суток

Чтобы определить сколько людей велосипед во время праздника, исследуйте данные 4-го июля праздник. Индексируйте в расписание ко временам строки на 4 июля 2015. Когда вы индексируете на временах строки, необходимо совпадать с временами точно. Можно задать индексы времени как datetime или duration значения, или как векторы символов, которые могут быть преобразованы в даты и времена. Можно задать многократно как массив.

Индексируйте в bikeData с определенными датами и временами, чтобы извлечь данные на 4 июля 2015. Если вы задаете дату только, то время принято, чтобы быть полуночью или 0:00:00.

bikeData('2015-07-04',:)
ans=1×4 timetable
           Time              Day       Total    Westbound    Eastbound
    ___________________    ________    _____    _________    _________

    2015-07-04 00:00:00    Saturday      8          7            1    

d = {'2015-07-04 08:00:00','2015-07-04 09:00:00'};
bikeData(d,:)
ans=2×4 timetable
           Time              Day       Total    Westbound    Eastbound
    ___________________    ________    _____    _________    _________

    2015-07-04 08:00:00    Saturday     15          3           12    
    2015-07-04 09:00:00    Saturday     21          4           17    

Это было бы утомительно, чтобы использовать эту стратегию извлечь целый день. Можно также указать диапазоны времени, не индексируя на определенных временах. Чтобы создать индекс области значений времени как помощника, используйте timerange функция.

Индекс в расписание с помощью времени располагается в течение целого дня от 4 июля 2015. Задайте время начала как полночь 4 июля и время окончания как полночь 5 июля. По умолчанию, timerange все случаи покрытий начиная со времени начала и до, но не включая, время окончания. Постройте велосипедные количества в течение дня.

tr = timerange('2015-07-04','2015-07-05');
jul4 = bikeData(tr,'Total');
head(jul4)
ans=8×1 timetable
           Time            Total
    ___________________    _____

    2015-07-04 00:00:00      8  
    2015-07-04 01:00:00     13  
    2015-07-04 02:00:00      4  
    2015-07-04 03:00:00      1  
    2015-07-04 04:00:00      0  
    2015-07-04 05:00:00      1  
    2015-07-04 06:00:00      8  
    2015-07-04 07:00:00     16  

bar(jul4.Time,jul4.Total)
ylabel('Bicycle Counts')
title('Bicycle Counts on July 4, 2015')

Из графика существует больше объема в течение дня, выравнивающегося днем. Поскольку многие компании закрываются, график не показывает типичный трафик в течение часов поездки на работу. Скачки позже вечером могут быть приписаны торжествам с фейерверками, которые происходят после наступления темноты. Чтобы исследовать эти тренды более тесно, данные должны сравниться с данными в течение типичных дней.

Сравните данные на 4 июля с данными для остальной части месяца июля.

jul = bikeData(timerange('2015-07-01','2015-08-01'),:);
plot(jul.Time,jul.Total)
hold on
plot(jul4.Time,jul4.Total)
ylabel('Total Count')
title('Bicycle Counts in July')
hold off
legend('Bicycle Count','July 4 Bicycle Count')

График показывает изменения, которые могут быть приписаны различиям в трафике между рабочими днями и выходными. Шаблоны трафика на 4 и 5 июля сопоставимы с шаблоном для трафика выходных дней. 5 июля понедельник, но часто наблюдается как праздник. Эти тренды могут быть исследованы более тесно с дальнейшей предварительной обработкой и анализом.

Предварительная обработка Времен и Данных Используя расписание

Наборы данных с меткой времени часто грязны и могут содержать аномалии или ошибки. Расписания хорошо подходят для решения аномалий и ошибок.

Расписание не должно иметь своих времен строки ни в каком конкретном порядке. Это может содержать строки, которые не сортируются по их временам строки. Расписание может также содержать несколько строк с тем же временем строки, хотя строки могут иметь различные значения данных. Даже когда времена строки сортируются и уникальны, они могут отличаться временными шагами различных размеров. Расписание может даже содержать NaT или NaN значения, чтобы указать недостающее время строки.

timetable тип данных обеспечивает много различных способов разрешить то, чтобы избегать, копию, или неоднородные времена. Можно также передискретизировать или агрегированные данные, чтобы создать обычное расписание. Когда расписание обычно, оно имеет времена строки, которые сортируются и уникальны, и иметь универсальную форму или равномерно распределенный временной шаг между ними.

  • Чтобы найти недостающие времена строки, используйте ismissing.

  • Чтобы удалить недостающие времена и данные, используйте rmmissing.

  • Чтобы отсортировать расписание к его временам строки, используйте sortrows.

  • Чтобы сделать расписание с уникальными и отсортированными временами строки, используйте unique и retime.

  • Чтобы сделать обычное расписание, задайте однородно расположенный с интервалами временной вектор и используйте retime.

Сортировка в порядке времени

Определите, сортируется ли расписание. Расписание сортируется, если его времена строки перечислены в порядке возрастания.

issorted(bikeData)
ans = logical
   0

Сортировка расписания. sortrows функциональные виды строки к их временам строки, от самого раннего до последнего времени. Если существуют строки с временами дублирующейся строки, то sortrows копии все копии к выходу.

bikeData = sortrows(bikeData);
issorted(bikeData)
ans = logical
   1

Идентификация и удаление недостающих времен и данных

Расписание может иметь индикаторы недостающих данных в своих переменных или его времена строки. Например, можно указать на недостающие числовые значения как на NaNs, и недостающие значения datetime как NaTs. Можно присвоить, найти, удалить и заполнить отсутствующие значения standardizeMissingismissingrmmissing, и fillmissing функции, соответственно.

Найдите и считайте отсутствующие значения в переменных расписания. В этом примере отсутствующие значения указывают на обстоятельства, когда никакие данные не были собраны.

missData = ismissing(bikeData);
sum(missData)
ans = 1×4

     1     3     3     3

Выход от ismissing logical матрица, тот же размер как таблица, идентифицируя пропускающий значения данных как верные. Отобразите любые строки, которые имеют индикаторы недостающих данных.

idx = any(missData,2);
bikeData(idx,:)
ans=3×4 timetable
           Time                Day        Total    Westbound    Eastbound
    ___________________    ___________    _____    _________    _________

    2015-08-03 00:00:00    Monday          NaN        NaN          NaN   
    2015-08-03 01:00:00    Monday          NaN        NaN          NaN   
    NaT                    <undefined>     NaN        NaN          NaN   

ismissing(bikeData) находит недостающие данные в переменных расписания только, не времена. Чтобы найти недостающие времена строки, вызовите ismissing на временах строки.

missTimes = ismissing(bikeData.Time);
bikeData(missTimes,:)
ans=2×4 timetable
    Time        Day        Total    Westbound    Eastbound
    ____    ___________    _____    _________    _________

    NaT     <undefined>     NaN        NaN          NaN   
    NaT     Friday            6          3            3   

В этом примере недостающие времена или значения данных указывают на погрешности измерения и могут быть исключены. Удалите строки таблицы, содержащей пропускающий значения данных и недостающие времена строки с помощью rmmissing.

bikeData = rmmissing(bikeData);
sum(ismissing(bikeData))
ans = 1×4

     0     0     0     0

sum(ismissing(bikeData.Time))
ans = 0

Удаление дублирующихся времен и данных

Определите, существуют ли дублирующиеся времена и/или дублирующиеся строки данных. Вы можете хотеть исключить точные копии, когда они могут также быть рассмотрены погрешностями измерения. Идентифицируйте дублирующиеся времена путем нахождения, где различие между отсортированными временами ниже нуля.

idx = diff(bikeData.Time) == 0;
dup = bikeData.Time(idx)
dup = 3x1 datetime
   2015-08-21 00:00:00
   2015-11-19 23:00:00
   2015-11-19 23:00:00

Три раза повторяются, и 19 ноября 2015 повторяется дважды. Исследуйте данные, сопоставленные с повторными временами.

bikeData(dup(1),:)
ans=2×4 timetable
           Time             Day      Total    Westbound    Eastbound
    ___________________    ______    _____    _________    _________

    2015-08-21 00:00:00    Friday     14          9            5    
    2015-08-21 00:00:00    Friday     11          7            4    

bikeData(dup(2),:)
ans=3×4 timetable
           Time              Day       Total    Westbound    Eastbound
    ___________________    ________    _____    _________    _________

    2015-11-19 23:00:00    Thursday     17         15            2    
    2015-11-19 23:00:00    Thursday     17         15            2    
    2015-11-19 23:00:00    Thursday     17         15            2    

Первое скопировало времена, но недублирующиеся данные, тогда как другие полностью дублированы. Строки расписания рассматриваются копиями, когда они содержат идентичные времена строки и идентичные значения данных через строки. Можно использовать unique удалить дублирующиеся строки в расписании. unique функционируйте также сортирует строки к их временам строки.

bikeData = unique(bikeData); 

Строки с дублирующимися временами, но недублирующимися данными требуют некоторой интерпретации. Исследуйте данные около тех времен.

d = dup(1) + hours(-2:2);
bikeData(d,:)
ans=5×4 timetable
           Time              Day       Total    Westbound    Eastbound
    ___________________    ________    _____    _________    _________

    2015-08-20 22:00:00    Thursday     40         30           10    
    2015-08-20 23:00:00    Thursday     25         18            7    
    2015-08-21 00:00:00    Friday       11          7            4    
    2015-08-21 00:00:00    Friday       14          9            5    
    2015-08-21 02:00:00    Friday        6          5            1    

В этом случае дублирующееся время, возможно, было ошибочно начиная с данных, и окружающие времена сопоставимы. Хотя это, кажется, представляет 1:00:00, сомнительно, во сколько это должно было быть. Данные могут быть накоплены с учетом данных в обоих моментах времени.

sum(bikeData{dup(1),2:end})
ans = 1×3

    25    16     9

Это - только один случай, который может быть сделан вручную. Однако для многих строк, retime функция может выполнить это вычисление. Накопите данные в течение уникальных времен с помощью sum функционируйте, чтобы агрегироваться. Сумма подходит для числовых данных, но не категориальных данных в расписании. Используйте vartype идентифицировать числовые переменные.

vt = vartype('numeric');
t = unique(bikeData.Time);
numData = retime(bikeData(:,vt),t,'sum');
head(numData)
ans=8×3 timetable
           Time            Total    Westbound    Eastbound
    ___________________    _____    _________    _________

    2015-06-24 00:00:00      13         9             4   
    2015-06-24 01:00:00       3         3             0   
    2015-06-24 02:00:00       1         1             0   
    2015-06-24 03:00:00       1         1             0   
    2015-06-24 04:00:00       1         1             0   
    2015-06-24 05:00:00       7         3             4   
    2015-06-24 06:00:00      36         6            30   
    2015-06-24 07:00:00     141        13           128   

Вы не можете суммировать категориальные данные, но поскольку одна метка представляет целый день, примите первое значение в каждый день. Можно выполнить retime операция снова с тем же временным вектором и конкатенирует расписания вместе.

vc = vartype('categorical');
catData = retime(bikeData(:,vc),t,'firstvalue');
bikeData = [catData,numData];
bikeData(d,:)
ans=4×4 timetable
           Time              Day       Total    Westbound    Eastbound
    ___________________    ________    _____    _________    _________

    2015-08-20 22:00:00    Thursday     40         30           10    
    2015-08-20 23:00:00    Thursday     25         18            7    
    2015-08-21 00:00:00    Friday       25         16            9    
    2015-08-21 02:00:00    Friday        6          5            1    

Исследование однородности временного интервала

Данные, кажется, имеют универсальный временной шаг одного часа. Чтобы определить, верно ли это в течение всех времен строки в расписании, используйте isregular функция. isregular возвращает true в течение отсортированных, равномерно распределенных времен (монотонно увеличивающийся), без копии или недостающие времена (NaT или NaN).

isregular(bikeData)
ans = logical
   0

Выход 0, или false, указывает, что времена в расписании равномерно не расположены с интервалами. Исследуйте временной интервал более подробно.

dt = diff(bikeData.Time);
[min(dt); max(dt)]
ans = 2x1 duration
   00:30:00
   03:00:00

Чтобы поместить расписание на интервал постоянного времени, используйте retime или synchronize и задайте временной интервал интереса.

Велосипедный объем Determine Daily

Определите количества в день с помощью retime функция. Накопите данные о количестве в течение каждого дня с помощью sum метод. Это подходит для числовых данных, но не категориальных данных в расписании. Используйте vartype идентифицировать переменные типом данных.

dayCountNum = retime(bikeData(:,vt),'daily','sum');
head(dayCountNum)
ans=8×3 timetable
           Time            Total    Westbound    Eastbound
    ___________________    _____    _________    _________

    2015-06-24 00:00:00    2141       1141         1000   
    2015-06-25 00:00:00    2106       1123          983   
    2015-06-26 00:00:00    1748        970          778   
    2015-06-27 00:00:00     695        346          349   
    2015-06-28 00:00:00     153         83           70   
    2015-06-29 00:00:00    1841        978          863   
    2015-06-30 00:00:00    2170       1145         1025   
    2015-07-01 00:00:00     997        544          453   

Как выше, можно выполнить retime операция снова, чтобы представлять категориальные данные с помощью соответствующего метода и конкатенировать расписания вместе.

dayCountCat = retime(bikeData(:,vc),'daily','firstvalue');
dayCount = [dayCountCat,dayCountNum];
head(dayCount)
ans=8×4 timetable
           Time               Day       Total    Westbound    Eastbound
    ___________________    _________    _____    _________    _________

    2015-06-24 00:00:00    Wednesday    2141       1141         1000   
    2015-06-25 00:00:00    Thursday     2106       1123          983   
    2015-06-26 00:00:00    Friday       1748        970          778   
    2015-06-27 00:00:00    Saturday      695        346          349   
    2015-06-28 00:00:00    Sunday        153         83           70   
    2015-06-29 00:00:00    Monday       1841        978          863   
    2015-06-30 00:00:00    Tuesday      2170       1145         1025   
    2015-07-01 00:00:00    Wednesday     997        544          453   

Синхронизация велосипедного количества и данных о погоде

Исследуйте эффект погоды на циклически повторяющемся поведении путем сравнения велосипедного количества с данными о погоде. Загрузите погодное расписание, которое включает исторические данные о погоде из Бостона, MA включая штормовые события.

load BostonWeatherData
head(weatherData)
ans=8×3 timetable
       Time        TemperatureF    Humidity       Events   
    ___________    ____________    ________    ____________

    01-Jul-2015         72            78       Thunderstorm
    02-Jul-2015         72            60       None        
    03-Jul-2015         70            56       None        
    04-Jul-2015         67            75       None        
    05-Jul-2015         72            67       None        
    06-Jul-2015         74            69       None        
    07-Jul-2015         75            77       Rain        
    08-Jul-2015         79            68       Rain        

Чтобы обобщить времена и переменные в расписании, используйте summary функция.

summary(weatherData)
RowTimes:

    Time: 383x1 datetime
        Values:
            Min           01-Jul-2015 
            Median        08-Jan-2016 
            Max           17-Jul-2016 
            TimeStep      24:00:00    

Variables:

    TemperatureF: 383x1 double

        Values:

            Min           2   
            Median       55   
            Max          85   

    Humidity: 383x1 double

        Values:

            Min          29   
            Median       64   
            Max          97   

    Events: 383x1 categorical

        Values:

            Fog                 7   
            Hail                1   
            Rain              108   
            Rain-Snow           4   
            Snow               18   
            Thunderstorm       12   
            None              233   

Объедините велосипедные данные с данными о погоде к общему временному вектору с помощью synchronize. Можно передискретизировать или совокупные данные о расписании с помощью любого из методов, зарегистрированных на странице с описанием для synchronize функция.

Синхронизируйте данные от обоих расписаний до общего временного вектора, созданного из пересечения их отдельных ежедневных временных векторов.

data = synchronize(dayCount,weatherData,'intersection');
head(data)
ans=8×7 timetable
           Time               Day       Total    Westbound    Eastbound    TemperatureF    Humidity       Events   
    ___________________    _________    _____    _________    _________    ____________    ________    ____________

    2015-07-01 00:00:00    Wednesday     997        544          453            72            78       Thunderstorm
    2015-07-02 00:00:00    Thursday     1943       1033          910            72            60       None        
    2015-07-03 00:00:00    Friday        870        454          416            70            56       None        
    2015-07-04 00:00:00    Saturday      669        328          341            67            75       None        
    2015-07-05 00:00:00    Sunday        702        407          295            72            67       None        
    2015-07-06 00:00:00    Monday       1900       1029          871            74            69       None        
    2015-07-07 00:00:00    Tuesday      2106       1140          966            75            77       Rain        
    2015-07-08 00:00:00    Wednesday    1855        984          871            79            68       Rain        

Сравните велосипедные количества трафика и наружную температуру на отдельных осях y, чтобы исследовать тренды. Удалите выходные из данных для визуализации.

idx = ~isweekend(data.Time);  
weekdayData = data(idx,{'TemperatureF','Total'});
figure
yyaxis left
plot(weekdayData.Time, weekdayData.Total) 
ylabel('Bicycle Count')
yyaxis right
plot(weekdayData.Time,weekdayData.TemperatureF) 
ylabel('Temperature (\circ F)')
title('Bicycle Counts and Temperature Over Time')
xlim([min(data.Time) max(data.Time)])

График показывает, что трафик и данные о погоде могут следовать за подобными трендами. Увеличьте масштаб графика.

xlim([datetime('2015-11-01'),datetime('2016-05-01')])

Тренды подобны, указав что меньше людей цикл в более холодные дни.

Анализ за день недели и времени суток

Исследуйте данные на основе различных интервалов, таких как день недели и времени суток. Определите общие количества в день с помощью varfun выполнять сгруппированные вычисления на переменных. Задайте sum функция с указателем на функцию и сгруппированной переменной и предпочтенным выходным типом с помощью пар "имя-значение".

byDay = varfun(@sum,bikeData,'GroupingVariables','Day',...
             'OutputFormat','table')
byDay=7×5 table
       Day       GroupCount    sum_Total    sum_Westbound    sum_Eastbound
    _________    __________    _________    _____________    _____________

    Sunday          1344         25315          12471            12844    
    Monday          1343         79991          39219            40772    
    Tuesday         1320         81480          39695            41785    
    Wednesday       1344         86853          41726            45127    
    Thursday        1344         87516          42682            44834    
    Friday          1342         76643          36926            39717    
    Saturday        1343         30292          14343            15949    

figure
bar(byDay{:,{'sum_Westbound','sum_Eastbound'}})
legend({'Westbound','Eastbound'},'Location','eastoutside')
xticklabels({'Sun','Mon','Tue','Wed','Thu','Fri','Sat'})
title('Bicycle Count by Day of Week')

Столбиковая диаграмма указывает, что трафик более тяжел в рабочие дни. Кроме того, существует различие в Идущих на восток и Движущихся на запад направлениях. Эта сила указывает, что люди склонны следовать различными маршрутами при вводе и отъезде города. Другая возможность состоит в том, что некоторые люди вводят в один день и возвращаются в другой день.

Определите час дня и используйте varfun для вычислений группой.

bikeData.HrOfDay = hour(bikeData.Time);
byHr = varfun(@mean,bikeData(:,{'Westbound','Eastbound','HrOfDay'}),...
    'GroupingVariables','HrOfDay','OutputFormat','table');
head(byHr)
ans=8×4 table
    HrOfDay    GroupCount    mean_Westbound    mean_Eastbound
    _______    __________    ______________    ______________

       0          389            5.4396            1.7686    
       1          389            2.7712           0.87147    
       2          391            1.8696           0.58312    
       3          391            0.7468             0.289    
       4          391           0.52685            1.0026    
       5          391           0.70588            4.7494    
       6          391            3.1228            22.097    
       7          391            9.1176             63.54    

bar(byHr{:,{'mean_Westbound','mean_Eastbound'}})
legend('Westbound','Eastbound','Location','eastoutside')
xlabel('Hour of Day')
ylabel('Bicycle Count')
title('Mean Bicycle Count by Hour of Day')

Существуют скачки трафика в типичные часы поездки на работу, около 9:00 a.m. и 5:00 p.m. Кроме того, тренды между Идущими на восток и Движущимися на запад направлениями отличаются. В общем случае Движущееся на запад направление находится к жилым районам, окружающим область Cambridge и к Университетам. Идущее на восток направление находится к Бостону.

Трафик более тяжел позже в тот же день в Движущемся на запад направлении по сравнению с Идущим на восток направлением. Эта сила указывает на университетские расписания и трафик из-за ресторанов в области. Исследуйте тренд за день недели, а также часа дня.

byHrDay = varfun(@sum,bikeData,'GroupingVariables',{'HrOfDay','Day'},...
    'OutputFormat','table');
head(byHrDay)
ans=8×6 table
    HrOfDay       Day       GroupCount    sum_Total    sum_Westbound    sum_Eastbound
    _______    _________    __________    _________    _____________    _____________

       0       Sunday           56           473            345              128     
       0       Monday           55           202            145               57     
       0       Tuesday          55           297            213               84     
       0       Wednesday        56           374            286               88     
       0       Thursday         56           436            324              112     
       0       Friday           55           442            348               94     
       0       Saturday         56           580            455              125     
       1       Sunday           56           333            259               74     

Чтобы расположить расписание так, чтобы дни недели были переменными, используйте unstack функция.

hrAndDayWeek = unstack(byHrDay(:,{'HrOfDay','Day','sum_Total'}),'sum_Total','Day'); 
head(hrAndDayWeek)
ans=8×8 table
    HrOfDay    Sunday    Monday    Tuesday    Wednesday    Thursday    Friday    Saturday
    _______    ______    ______    _______    _________    ________    ______    ________

       0        473        202       297         374          436        442       580   
       1        333         81       147         168          173        183       332   
       2        198         77        68          93          128        141       254   
       3         86         41        43          44           50         61        80   
       4         51         81       117         101          108         80        60   
       5        105        353       407         419          381        340       128   
       6        275       1750      1867        2066         1927       1625       351   
       7        553       5355      5515        5818         5731       4733       704   

ribbon(hrAndDayWeek.HrOfDay,hrAndDayWeek{:,2:end})
ylim([0 24])
xlim([0 8])
xticks(1:7)
xticklabels({'Sun','Mon','Tue','Wed','Thu','Fri','Sat'})
ylabel('Hour')
title('Bicycle Count by Hour and Day of Week')

Существуют подобные тренды в течение дней постоянной работы понедельника в течение пятницы с peaks в час пик и трафик, сужающийся вечером. Пятница имеет меньше объема, хотя общая тенденция похожа на другие рабочие дни. Тренды в течение субботы и воскресенья похожи друг на друга без peaks часа пик и с большим количеством объема позже в тот же день. Тренды позднего вечера также подобны в течение понедельника в течение пятницы с меньшим количеством объема в пятницу.

Анализ трафика в течение часа пик

Чтобы исследовать полные тренды времени суток, разделите данные ко временам часа пик. Возможно использовать различное время суток или модули времени с помощью discretize функция. Например, разделите данные на группы для AM, AMRushдень, PMRush\pm. Затем используйте varfun вычислить среднее значение группой.

bikeData.HrLabel = discretize(bikeData.HrOfDay,[0,6,10,15,19,24],'categorical',...
    {'AM','RushAM','Day','RushPM','PM'});
byHrBin = varfun(@mean,bikeData(:,{'Total','HrLabel'}),'GroupingVariables','HrLabel',...
    'OutputFormat','table')
byHrBin=5×3 table
    HrLabel    GroupCount    mean_Total
    _______    __________    __________

    AM            2342         3.5508  
    RushAM        1564         94.893  
    Day           1955         45.612  
    RushPM        1564         98.066  
    PM            1955         35.198  

bar(byHrBin.mean_Total)
cats = categories(byHrBin.HrLabel);
xticklabels(cats)
title('Mean Bicycle Count During Rush Hours')

В общем случае существует о вдвое большем количестве трафика в этой области в течение вечерних и утренних часов пик по сравнению с другими временами дня. Существует очень мало трафика в этой области рано утром, но существует все еще значительный трафик вечерним и поздним вечером, сопоставим со днем за пределами утренних и вечерних часов пик.

Смотрите также

| | | | | | | | | |

Похожие темы