Ранее мы отметили, что библиотека pandas прекрасно справляется с работой с датами. Однако она столь же эффективна в операциях с текстовыми данными. Давайте вернемся к исходным данным из предыдущей части.

In [1]:
%matplotlib inline
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

pd.options.display.max_rows = 7
plt.style.use('ggplot')
plt.rcParams['figure.figsize'] = (15, 3)
plt.rcParams['font.family'] = 'sans-serif'
In [2]:
weather_2012 = pd.read_csv('data/weather_2012.csv', parse_dates=True, index_col='Date/Time')
weather_2012[:5]
Out[2]:
Temp (C) Dew Point Temp (C) Rel Hum (%) Wind Spd (km/h) Visibility (km) Stn Press (kPa) Weather
Date/Time
2012-01-01 00:00:00 -1.8 -3.9 86 4 8.0 101.24 Fog
2012-01-01 01:00:00 -1.8 -3.7 87 4 8.0 101.24 Fog
2012-01-01 02:00:00 -1.8 -3.4 89 7 4.0 101.26 Freezing Drizzle,Fog
2012-01-01 03:00:00 -1.5 -3.2 88 6 4.0 101.27 Freezing Drizzle,Fog
2012-01-01 04:00:00 -1.5 -3.3 88 7 4.8 101.23 Fog

Работа с текстовыми данными в pandas

Погоду за каждый час описывает столбец 'Weather'. Допустим, что запись о снежной погоде включает слово "Snow".

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

In [3]:
weather_description = weather_2012['Weather']
is_snowing = weather_description.str.contains('Snow')

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

In [4]:
is_snowing[:5]
Out[4]:
Date/Time
2012-01-01 00:00:00    False
2012-01-01 01:00:00    False
2012-01-01 02:00:00    False
2012-01-01 03:00:00    False
2012-01-01 04:00:00    False
Name: Weather, dtype: bool
In [5]:
is_snowing.plot()
Out[5]:
График погоды

Находим месяцы с максимальным количеством выпавшего снега

Чтобы вычислить медианную температуру за каждое месяц, необходимо применить метод resample(), как в приведенном далее примере:

In [6]:
weather_2012['Temp (C)'].resample('M').median().plot(kind='bar')
Out[6]:
Температурный график

Неожиданно, самыми жаркими оказались июль и август.

Что касается снега, вместо значений True или False мы можем рассматривать наш вектор как состоящий из нулей и единиц:

In [7]:
is_snowing.astype(int)[:10]
Out[7]:
Date/Time
2012-01-01 00:00:00    0
2012-01-01 01:00:00    0
2012-01-01 02:00:00    0
                      ..
2012-01-01 07:00:00    0
2012-01-01 08:00:00    0
2012-01-01 09:00:00    0
Name: Weather, dtype: int64

а затем применить метод resample, чтобы определить процент времени, когда снег действительно выпадал.

In [8]:
is_snowing.astype(int).resample('M').mean()
Out[8]:
Date/Time
2012-01-31    0.240591
2012-02-29    0.162356
2012-03-31    0.087366
                ...
2012-10-31    0.000000
2012-11-30    0.038889
2012-12-31    0.251344
Freq: M, Name: Weather, dtype: float64
In [9]:
is_snowing.astype(int).resample('M').mean().plot(kind='bar')
Out[9]:
График выпадения снега

Теперь мы убедились! В 2012 году самым снежным оказался декабрь.

Объединяем графики температур и снежных условий

Для большей наглядности объединим эти две статистики в один DataFrame, затем изобразим их вместе:

In [10]:
temperature = weather_2012['Temp (C)'].resample('M').median()
is_snowing = weather_2012['Weather'].str.contains('Snow')
snowiness = is_snowing.astype(int).resample('M').mean()

# Name the columns
temperature.name = "Temperature"
snowiness.name = "Snowiness"

Используйте concat для объединения этих колонок в единый DataFrame.

In [11]:
stats = pd.concat([temperature, snowiness], axis=1)
stats
Out[11]:
Temperature Snowiness
Date/Time
2012-01-31 -7.05 0.240591
2012-02-29 -4.10 0.162356
2012-03-31 2.60 0.087366
... ... ...
2012-10-31 11.30 0.000000
2012-11-30 1.05 0.038889
2012-12-31 -2.85 0.251344

12 rows × 2 columns

In [12]:
stats.plot(kind='bar')
Out[12]:
Результат объединения графиков температур и снежных условий

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

In [13]:
stats.plot(kind='bar', subplots=True, figsize=(15, 10))
Out[13]:
array([,
       ], dtype=object)
Раздельные графики на двух разных осях

Вопросы для самопроверки:

  1. Какой метод библиотеки pandas используется для работы с текстовыми данными в столбцах?
  2. Какую операцию выполняет метод `resample()` в процессе анализа данных?
  3. С использованием какого метода объединяются две статистики в один DataFrame?
  4. Каким образом отобразить два графика на разных осях?