Рубрики
Без рубрики

Как использовать Python и Pandas для карты крупных штормов, пессимизма и жестких данных

Автор оригинала: David Clinton.

Иногда можно как-то утешать, насколько все хуже всего, чем это было в старые добрые времена.

«Дети не имеют уважения».

«Все обосновано слишком много».

«Государственные чиновники не вдохновляют доверие».

«А как насчет погоды? Мы никогда не использовали получить так много разрушительных ураганов, мы?»

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

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

Во-первых, мы должны тщательно определить некоторые термины и заполнить некоторые детали фона.

Что такое крупный шторм?

Ураганы – или, точнее, тропические циклоны – «тропические» в том смысле, что они образуют над океанами в тропических регионах. Термин «тропики» относится к области поверхности Земли, которая падает в течение 23 градусов (или около того) экватора, как к ее северу, так и на юге.

Штормы называются «циклонами», потому что движение их ветров является циклическим (по часовой стрелке в южном полушарии и против часовой стрелки в северном полушарии).

Циклоны питаются испарительными океанской водой и оставляют проливными и часто насильственными грозами, особенно после дрейфов над привлеченными земельными участками.

В широком выражении штормовое производство устойчивых ветров от около 34 и 63 узлов (или от 39 до 72 миль в час) считается тропическим штормом. Штормы с ветрами выше 64 узла (73 миль в час) являются ураганами (или, в западной части Тихого океана или на северных Индийских океанах, тайфуны).

Ураганы измеряются по категориям от одного до пяти, где ураганы категории пять являются наиболее насильственными и опасными.

Откуда приходят основные штормовые данные?

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

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

Перед открытием Панамы Канал в 1914 году корабли, путешествующие между Европой и Тихим океаном, будут следить за маршрутом на южной оконечности Южной Америки, который в значительной степени пропустил прибрежные районы США. В результате, вероятно, что значительный процент погоды были просто пропущены.

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

Эти изменения, и их влияние на штормовые данные аккуратно обобщены На этой странице От участия в правительстве США Национального океанического и атмосферного администрирования (NOAA), основанного на Исследование анализа данных Выполняется для геофизической лаборатории динамики жидкости (GFDL).

Что показывает исторический рекорд?

Так ведь этот фон, что на самом деле говорят данные? Серьезные ураганы чаще, чем в прошлом? Ну, согласно веб-сайте NOAA, ответ: «Нет.» Вот как они поставили это :

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

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

Данные урагана США: 1851-2019

Наш источник для «Continental United States Hurricane Heads/Landfalls» – это Эта веб-страница NOAA Отказ

Для загрузки данных я просто скопировал его, щелкнув мою мышь в левом верхнем углу («Год» заголовка) и перетаскивая весь путь до нижнего правого. Затем я вставил его в редактор с обычным текстом на моем локальном компьютере и сохранил его в файл с расширением .csv Отказ

Как очистить данные ураганов

Если вы быстро смотрите через саму веб-страницу, вы увидите некоторые форматирование, которые нуждается в уборке. Каждое десятилетие вводится с одним ряд, содержащим ничего, кроме строки, похожей на: 1850-х годов Отказ Мы захочем просто бросить эти ряды. Годы без событий содержат строку Нет во втором столбце. Те тоже должны поехать.

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

И, наконец, в то время как месяцы, как правило, представляются трехбуквенными сокращениями, была пара событий, которые простирались через два месяца. Так что мы сможем правильно обрабатывать тех, я поэтому конвертировать SP-OC и JL-AU к Сен и Июл соответственно.

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

Вот как мы настроили вещи в Jupyter:

import pandas as pd
import matplotlib as plt
import matplotlib.pyplot as plt 
import numpy as np

df = pd.read_csv('all-us-hurricanes-noaa.csv')

Давайте посмотрим на типы данных для каждого столбца. Мы можем игнорировать строки в колонке состояний и имени – мы все равно не заинтересованы в этом. Но нам нужно что-то сделать с датой и максимальными ветряными колоннами – они не будут делать нам никакой пользы, как объект Отказ

df.dtypes

Year                                         object
Month                                        object
States Affected and Category by States       object
Highest\nSaffir-\nSimpson\nU.S. Category    float64
Central Pressure\n(mb)                      float64
Max Wind\n(kt)                               object
Name                                         object
dtype: object

Так что я фильтрую все строки в Год Столбец для буквы S И просто бросить их ( == false ). Это позаботится обо всех заголовках десятилетия (то есть этих строк, содержащих S как часть чего-то вроде 1850s ).

Я так же брось, содержащие строку Нет В Месяц Колонна для устранения лет без штормов.

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

Наконец, я заменим эти два многомесячных ряда.

df = df[(df.Year.str.contains("s")) == False]
df = df[(df.Month.str.contains("None")) == False]
df = df.replace('Sp-Oc','Sep')
df = df.replace('Jl-Au','Jul')

Далее я буду использовать удобные панды для datetime Метод преобразования трехбуквенного месяца сокращений до номеров от 1 до 12. Код формата % b является одним из юридических обозначений, связанных с датой Python и говорит Python, который мы работаем с более трехбуквенным аббревиатурой. Для полного списка см. эта страница.

df.Month = pd.to_datetime(df.Month, format='%b').dt.month

Я хотел бы немного затянуть заголовки, чтобы они немного проще, и ссылаться в наш код. DF.Columns Изменит все значения заголовка столбца в список, который я указываю здесь:

df.columns =['Year', 'Month', 'States', 'Category', 
             'Pressure', 'Max Wind', 'Name']  

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

Как рекламируется, я также конвертирую NULL ( ------ ) значения в Макс ветер к Нан – который Numpy будет читать как «не число». Затем я преобразую данные в Макс ветер от объект к плавать Отказ

df = df.astype({'Year': 'int'})
df = df.replace('-----',np.NaN)
df = df.astype({'Max Wind': 'float'})

Давайте посмотрим, как все, что выглядит сейчас:

df.dtypes

Year          int64
Month         int64
States       object
Category    float64
Pressure    float64
Max Wind    float64
Name         object
dtype: object

Намного лучше.

Как представить данные ураганов

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

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

Конечно, я всегда могу изолировать индивидуальные метрики, чтобы увидеть, как будут выглядеть их распределения. Использование Value_Counts против Категория Например, столбец показывает, что более легкая категория 1 и 2 ураганов гораздо чаще, чем более опасные события.

df['Category'].value_counts()

1.0    121
2.0     83
3.0     62
4.0     25
5.0      4
Name: Category, dtype: int64

И построение одной гистограммы полного набора данных дает нам приятный обзор количества событий (представленных на оси Y) благодаря истории, но мы можем потерять некоторые из более тонких деталей в процессе.

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

df.hist(column='Year', bins=25)

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

df_category = df[['Year','Category']]
df_wind = df[['Year','Max Wind']]
df_pressure = df[['Year','Pressure']]

Отправка каждого из этих данных DataFrames прямо к сюжету пропустит точку, потому что она не различает серьезность штормов. Поэтому я покажу вам, как мы можем разбить данные по категориям (1-5). Это для Цикл переживает через цифры 1-6 (который является «Python» для возврата чисел от 1 до 5) и использует каждый из этих чисел в очереди к поиску ураганов этой категории.

Ряды, категория которых соответствует числете, будет записан на новый (временный) dataframe, называемый DF1 который будет, в свою очередь, будет использоваться для построения гистограммы. PLT.TITLE Линия применяет заголовок для печатного графика, который будет включать в себя номер категории (текущее значение Converted_num ).

Цикл будет работать через процесс пять раз, каждый раз написание количества событий текущей категории для DF1 Отказ Все пять гистограмм будут напечатаны, один за другим.

for x in range(1, 6):
    cat_num = x
    converted_num = str(cat_num) 
    dfcat = df_category['Category']==(x)
    df1 = df_category[dfcat]
    df1.hist(column='Year', bins=20)
    plt.title("Total Category " + (converted_num) + " Events")

Как видите, нет заметных доказательств значительно растущих частоты шторма со временем.

Как всегда, сканируйте ваши данные (используя инструменты, такие как Value_Counts () ), чтобы подтвердить, что участки имеют смысл в реальном мире.

Данные тропические шторма США: 1851-1965, 1983-2019

Ураганы (или циклоны), конечно, только одна часть истории. Повышение частоты разрушительных тропических штормов также будет причиной для беспокойства.

К счастью, NOAA делает соответствующие данные доступными в том же формате, что и их данные ураганов. Вот веб-страница где вы найдете график. Скопируйте данные в .csv файл так же, как и раньше.

Обратите внимание, однако, как нет данных на 1966-1982 годы. Не спрашивайте меня, почему. Там просто нет. Забавная вещь, погода.

Я бы создал новую ноутбуку Jupyter для этой части проекта, так как нет ничего, что нам нужно от версии урагана. Поэтому вы будете настроить все всегда:

import pandas as pd
import matplotlib as plt
import numpy as np
df = pd.read_csv('all-us-tropical-storms-noaa.csv')

Давайте убрать данные тропических штормов

Ряды, представляющие годы без событий, снова должны быть удалены:

df = df[(df.Date.str.contains("None")) == False]

Дата Столбец в этом наборе данных имеет символы, указывающие на пять сносок: $, *, #,% и &. Сноски содержат важную информацию, но эти персонажи дадут нам горе, если мы не удалим их.

Эти команды сделают это, заменяя все такие строки в Дата Колонка без ничего:

df['Date'] = df.Date.str.replace('\$', '')
df['Date'] = df.Date.str.replace('\*', '')
df['Date'] = df.Date.str.replace('\#', '')
df['Date'] = df.Date.str.replace('\%', '')
df['Date'] = df.Date.str.replace('\&', '')

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

df.columns =['Storm#', 'Date', 'Time', 'Lat', 'Lon', 
             'MaxWinds', 'LandfallState', 'StormName'] 

Типы данных столбцов понадобится некоторую работу:

df.dtypes

Storm#            object
Date              object
Time              object
Lat               object
Lon               object
MaxWinds         float64
LandfallState     object
StormName         object
dtype: object

Давайте посмотрим, как выглядит наши данные:

df.head()

Storm#	Date		Time	Lat	Lon	MaxWindsLandfallState	StormName
6	10/19/1851	1500Z	41.1N	71.7W	50.0	NY	NaN
3	8/19/1856	1100Z	34.8	76.4	50.0	NC	NaN
4	9/30/1857	1000Z	25.8	97	50.0	TX	NaN
3	9/14/1858	1500Z	27.6	82.7	60.0	FL	NaN
3	9/16/1858	0300Z	35.2	75.2	50.0	NC	NaN

Я на самом деле не уверен, что те Шторм # Значения все о том, но они никому не причиняют боль. Даты отформатированы намного лучше, чем они были для данных ураганов. Но мне нужно будет преобразовать их в новый формат. Давайте сделаем это правильно и пойти с datetime Отказ

df.Date = pd.to_datetime(df.Date)

Как представить тропические штормовые данные

Для наших целей единственным столбцем данных, которые действительно имеют значение, это MaxWinds – как то, что определяет интенсивность шторма. Эта команда создаст новый DataFrame, состоит из Дата и MaxWinds Колонны:

df1 = df[['Date','MaxWinds']]

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

df1['Date'].hist()

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

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

print(df1.shape)

(362, 2)

Печать нашего DataFrame показывает нам, что MaxWinds Значения – это все это кратные 5. Если вы сканируете данные для себя, вы увидите, что они варьируются от 30 до 70 или около того.

df1

	Date		MaxWinds
1	1851-10-19	50.0
6	1856-08-19	50.0
7	1857-09-30	50.0
8	1858-09-14	60.0
9	1858-09-16	50.0
...	...	...
391	2017-09-27	45.0
392	2018-05-28	40.0
393	2018-09-03	45.0
394	2018-09-03	45.0
395	2019-09-17	40.0
362 rows × 2 columns

Итак, давайте разделим наши данные на четыре меньших множества в качестве разумных прокси для штормов различных уровней интенсивности. Я создал четырех данных и заполнил их событиями, падающими в их узкие диапазоны (то есть от 30 до 39 узлов, 40 и 49, 50 и 59 и 60 и 79). Это должно дать нам разумную систему для наших событий.

df_30 = df1[df1['MaxWinds'].between(30, 39)]
df_40 = df1[df1['MaxWinds'].between(40, 49)]
df_50 = df1[df1['MaxWinds'].between(50, 59)]
df_60 = df1[df1['MaxWinds'].between(60, 79)]

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

st1 = len(df_30.index)
print('The number of storms between 30 and 39: ', st1)
st2 = len(df_40.index)
print('The number of storms between 40 and 49: ', st2)
st3 = len(df_50.index)
print('The number of storms between 50 and 59: ', st3)
st4 = len(df_60.index)
print('The number of storms between 60 and 79: ', st4)

The number of storms between 30 and 39:  51
The number of storms between 40 and 49:  113
The number of storms between 50 and 59:  142
The number of storms between 60 and 79:  56

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

Мы также могли бы выглядеть немного глубже в данные, используя наш старый друг, value_counts () Отказ Это покажет нам, что было 71 40 узел событий и события 42 45 узлов на протяжении всего нашего временного диапазона.

df_40['MaxWinds'].value_counts()

40.0    71
45.0    42
Name: MaxWinds, dtype: int64

Мы можем построить один линейный график для отображения всех четырех наших подмножеств вместе. Этот участок добавляет оси и сюжетные этикетки и легенда, чтобы дать данные проще понять. subplot (111) Значение контролирует размер фигуры.

import matplotlib.pyplot as plt
fig = plt.figure()
ax = plt.subplot(111)
df_30['MaxWinds'].plot(ax=ax, label='df_30')
df_40['MaxWinds'].plot(ax=ax, label='df_40')
df_50['MaxWinds'].plot(ax=ax, label='df_50')
df_60['MaxWinds'].plot(ax=ax, label='df_60')
ax.set_ylabel('Wind Speed In Knots')
ax.set_xlabel('Time Between 1851 and 2019')
plt.title('Tropical Storms by Maximum Wind Speeds (knots)')
ax.legend()

Это может быть полезно для подтверждения того, что мы не делаем беспорядок самих данных. Проверка визуально покажет, например, то, что в нашем наборе данных произошла только одному событию 30 узлов, и что имело место к концу наших временных кадров в 2016 году. Но это не отличный способ показать нам изменения в событии частота.

Для этого мы посмотрим на данные, проводимые в каждом из наших данных.

df_30['Date'].hist(bins=20)
df_40['Date'].hist(bins=20)
df_50['Date'].hist(bins=20)
df_60['Date'].hist(bins=20)

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

Вы можете найти гораздо большего содержания технологий по Дэвид Клинтон через свой сайт. В частности, вы можете наслаждаться своей новой книгой, Поддержка: бутылки всем большим технологическим тенденциям, которые вы не можете позволить себе игнорировать Отказ