Как объединить данные из нескольких таблиц?

In [1]: import pandas as pd
Данные, использованные в этом уроке:
  • В этом руководстве используются данные о концентрации \(NO_2\) в воздухе, предоставленные openaq и использующие пакет py-openaq.

    Набор данных air_quality_no2.csv содержит значения \(NO_2\), полученные от измерительных станций FR04014, BETR801 и London Westminster в Париже, Антверпене и Лондоне соответственно.

    Исходные данные
    In [2]: air_quality_no2 = pd.read_csv("data/air_quality_no2_long.csv",
       ...:                               parse_dates=True)
       ...: 
    
    In [3]: air_quality_no2 = air_quality_no2[["date.utc", "location",
       ...:                                    "parameter", "value"]]
       ...: 
    
    In [4]: air_quality_no2.head()
    Out[4]: 
                        date.utc location parameter  value
    0  2019-06-21 00:00:00+00:00  FR04014       no2   20.0
    1  2019-06-20 23:00:00+00:00  FR04014       no2   21.8
    2  2019-06-20 22:00:00+00:00  FR04014       no2   26.5
    3  2019-06-20 21:00:00+00:00  FR04014       no2   24.9
    4  2019-06-20 20:00:00+00:00  FR04014       no2   21.4
    
  • В этом руководстве используются данные о твердых частицах размером менее 2,5 микрометров, предоставленные openaq и загруженные с помощью py-openaq.

    Набор данных air_quality_pm25_long.csv содержит значения \(PM_{25}\), полученные от измерительных станций FR04014, BETR801 и London Westminster в Париже, Антверпене и Лондоне соответственно.

    Исходные данные
    In [5]: air_quality_pm25 = pd.read_csv("data/air_quality_pm25_long.csv",
       ...:                                parse_dates=True)
       ...: 
    
    In [6]: air_quality_pm25 = air_quality_pm25[["date.utc", "location",
       ...:                                      "parameter", "value"]]
       ...: 
    
    In [7]: air_quality_pm25.head()
    Out[7]: 
                        date.utc location parameter  value
    0  2019-06-18 06:00:00+00:00  BETR801      pm25   18.0
    1  2019-06-17 08:00:00+00:00  BETR801      pm25    6.5
    2  2019-06-17 07:00:00+00:00  BETR801      pm25   18.5
    3  2019-06-17 06:00:00+00:00  BETR801      pm25   16.0
    4  2019-06-17 05:00:00+00:00  BETR801      pm25    7.5
    

Объединение объектов

../../_images/08_concat_row.svg
  • Я хочу объединить измерения \(NO_2\) и \(PM_{25}\) из двух таблиц с похожей структурой в одну таблицу.

    In [8]: air_quality = pd.concat([air_quality_pm25, air_quality_no2], axis=0)
    
    In [9]: air_quality.head()
    Out[9]: 
                        date.utc location parameter  value
    0  2019-06-18 06:00:00+00:00  BETR801      pm25   18.0
    1  2019-06-17 08:00:00+00:00  BETR801      pm25    6.5
    2  2019-06-17 07:00:00+00:00  BETR801      pm25   18.5
    3  2019-06-17 06:00:00+00:00  BETR801      pm25   16.0
    4  2019-06-17 05:00:00+00:00  BETR801      pm25    7.5
    

    Функция concat() выполняет операции конкатенации нескольких таблиц по одной из осей (по строкам или по столбцам).

По умолчанию конкатенация выполняется по оси 0, поэтому результирующая таблица объединяет строки входных таблиц. Давайте проверим форму исходной и объединенной таблиц, чтобы проверить операцию:

In [10]: print('Shape of the ``air_quality_pm25`` table: ', air_quality_pm25.shape)
Shape of the ``air_quality_pm25`` table:  (1110, 4)

In [11]: print('Shape of the ``air_quality_no2`` table: ', air_quality_no2.shape)
Shape of the ``air_quality_no2`` table:  (2068, 4)

In [12]: print('Shape of the resulting ``air_quality`` table: ', air_quality.shape)
Shape of the resulting ``air_quality`` table:  (3178, 4)

Следовательно, в результирующей таблице 3178 = 1110 + 2068 строк.

Примечание

Некоторые методы pandas, которые можно применять вдоль оси, включают аргумент axis. DataFrame имеет две оси: первая проходит вертикально вниз по строкам (ось 0), а вторая проходит горизонтально по столбцам (ось 1). Большинство операций, таких как конкатенация или сводная статистика, по умолчанию выполняются по строкам (ось 0), но могут применяться и по столбцам.

Сортировка таблицы по дате и времени также иллюстрирует комбинацию обеих таблиц, где по столбцу parameter можно определить происхождение таблицы (либо no2 из таблицы air_quality_no2, либо pm25 из air_quality_pm25):

In [13]: air_quality = air_quality.sort_values("date.utc")

In [14]: air_quality.head()
Out[14]: 
                       date.utc            location parameter  value
2067  2019-05-07 01:00:00+00:00  London Westminster       no2   23.0
1003  2019-05-07 01:00:00+00:00             FR04014       no2   25.0
100   2019-05-07 01:00:00+00:00             BETR801      pm25   12.5
1098  2019-05-07 01:00:00+00:00             BETR801       no2   50.5
1109  2019-05-07 01:00:00+00:00  London Westminster      pm25    8.0

В нашем примере столбец parameter из исходных данных гарантирует, что каждую из объединяемых таблиц можно будет идентифицировать. Это не всегда так. Функция concat в таких случаях предоставляет удобное решение в виде аргумента keys, с помощью которого добавляется дополнительный (иерархический) индекс строки. Например:

In [15]: air_quality_ = pd.concat([air_quality_pm25, air_quality_no2], keys=["PM25", "NO2"])
In [16]: air_quality_.head()
Out[16]: 
                         date.utc location parameter  value
PM25 0  2019-06-18 06:00:00+00:00  BETR801      pm25   18.0
     1  2019-06-17 08:00:00+00:00  BETR801      pm25    6.5
     2  2019-06-17 07:00:00+00:00  BETR801      pm25   18.5
     3  2019-06-17 06:00:00+00:00  BETR801      pm25   16.0
     4  2019-06-17 05:00:00+00:00  BETR801      pm25    7.5

Примечание

В нашем руководстве не говорилось о существовании одновременно нескольких индексов строк или столбцов. Иерархическая индексация или MultiIndex — это мощная функция pandas продвинутого уровня для анализа многомерных данных.

Мультииндексация выходит за рамки этого введения в pandas. Пока запомните, что функцию reset_index можно использовать для преобразования любого уровня индекса в столбец, например, air_quality.reset_index(level=0).

В руководстве пользователя

Не стесняйтесь погрузиться в мир мультииндексирования в разделе руководства пользователя о продвинутом индексировании.

В руководстве пользователя

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

Объединение таблиц с использованием общего идентификатора

../../_images/08_merge_left.svg
  • Добавить координаты станций из таблицы метаданных станций в соответствующие строки таблицы измерений.

    Предупреждение

    Координаты станций измерения качества воздуха хранятся в файле данных air_quality_stations.csv, загружаемом с помощью пакета py-openaq.

    In [17]: stations_coord = pd.read_csv("data/air_quality_stations.csv")
    
    In [18]: stations_coord.head()
    Out[18]: 
      location  coordinates.latitude  coordinates.longitude
    0  BELAL01              51.23619                4.38522
    1  BELHB23              51.17030                4.34100
    2  BELLD01              51.10998                5.00486
    3  BELLD02              51.12038                5.02155
    4  BELR833              51.32766                4.36226
    

    Примечание

    Станции, использованные в этом примере (FR04014, BETR801 и London Westminster) — это всего лишь три записи в таблице метаданных. Мы только хотим добавить их координаты в таблицу измерений, в соответствующих строках таблицы air_quality.

    In [19]: air_quality.head()
    Out[19]: 
                           date.utc            location parameter  value
    2067  2019-05-07 01:00:00+00:00  London Westminster       no2   23.0
    1003  2019-05-07 01:00:00+00:00             FR04014       no2   25.0
    100   2019-05-07 01:00:00+00:00             BETR801      pm25   12.5
    1098  2019-05-07 01:00:00+00:00             BETR801       no2   50.5
    1109  2019-05-07 01:00:00+00:00  London Westminster      pm25    8.0
    
    In [20]: air_quality = pd.merge(air_quality, stations_coord, how="left", on="location")
    
    In [21]: air_quality.head()
    Out[21]: 
                        date.utc            location parameter  value  coordinates.latitude  coordinates.longitude
    0  2019-05-07 01:00:00+00:00  London Westminster       no2   23.0              51.49467               -0.13193
    1  2019-05-07 01:00:00+00:00             FR04014       no2   25.0              48.83724                2.39390
    2  2019-05-07 01:00:00+00:00             FR04014       no2   25.0              48.83722                2.39390
    3  2019-05-07 01:00:00+00:00             BETR801      pm25   12.5              51.20966                4.43182
    4  2019-05-07 01:00:00+00:00             BETR801       no2   50.5              51.20966                4.43182
    

    С помощью функции merge() в каждую строку таблицы air_quality добавляются соответствующие координаты из таблицы stations_coord. Обе таблицы имеют общий столбец location, который используется в качестве ключа для объединения данных. При выборе объединения left в результирующую таблицу попадают только станции, доступные в таблице air_quality (слева), т. е. FR04014, BETR801 и London Westminster. Функция merge поддерживает несколько вариантов объединения, аналогичных операциям в базах данных.

  • Добавить в таблицу измерений полное описание и имя параметра из таблицы метаданных параметров.

    Предупреждение

    Метаданные параметров качества воздуха хранятся в файле данных air_quality_parameters.csv, загружаемом с помощью пакета py-openaq.

    In [22]: air_quality_parameters = pd.read_csv("data/air_quality_parameters.csv")
    
    In [23]: air_quality_parameters.head()
    Out[23]: 
         id                                        description  name
    0    bc                                       Black Carbon    BC
    1    co                                    Carbon Monoxide    CO
    2   no2                                   Nitrogen Dioxide   NO2
    3    o3                                              Ozone    O3
    4  pm10  Particulate matter less than 10 micrometers in...  PM10
    
    In [24]: air_quality = pd.merge(air_quality, air_quality_parameters,
       ....:                        how='left', left_on='parameter', right_on='id')
       ....: 
    
    In [25]: air_quality.head()
    Out[25]: 
                        date.utc            location  ...                                        description   name
    0  2019-05-07 01:00:00+00:00  London Westminster  ...                                   Nitrogen Dioxide    NO2
    1  2019-05-07 01:00:00+00:00             FR04014  ...                                   Nitrogen Dioxide    NO2
    2  2019-05-07 01:00:00+00:00             FR04014  ...                                   Nitrogen Dioxide    NO2
    3  2019-05-07 01:00:00+00:00             BETR801  ...  Particulate matter less than 2.5 micrometers i...  PM2.5
    4  2019-05-07 01:00:00+00:00             BETR801  ...                                   Nitrogen Dioxide    NO2
    
    [5 rows x 9 columns]
    

    По сравнению с предыдущим примером здесь нет общего имени столбца. Однако столбец parameter в таблице air_quality и столбец id в air_quality_parameters предоставляют измеренную переменную в общем формате. Вместо простого аргумента on здесь используются аргументы left_on и right_on для создания связи между двумя таблицами.

В руководстве пользователя

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

ЗАПОМНИТЕ

  • Несколько таблиц можно объединить как по столбцам, так и по строкам с помощью функции concat.

  • Для объединения таблиц по аналогии с базами данных используйте функцию merge.

В руководстве пользователя

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