Как соединить два датафрейма pandas

от admin

5 Расширенных возможностей Pandas и как ими пользоваться

Pandas — это золотой стандарт в обработке данных. А функциональные возможности библиотеки по загрузке, фильтрации, обработке и изучению данных быстро сделали ее излюбленным инструментом аналитиков.

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

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

(1) Настройка опций и параметров

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

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

В коде выше показывается, что Pandas может отображать не более 10 строк и 10 столбцов, а максимально допустимое количество знаков после запятой — 2. Таким образом, при добавлении большого DataFrame в терминал или Jupyter Notebook, он не превратится в мешанину из данных.

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

(2) Объединение DataFrame

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

Конкатенация

Конкатенация относится к самым известным методам объединения фреймов данных; ее можно рассматривать, как «стекинг». И этот самый стекинг бывает вертикальным или горизонтальным.

К примеру, у вас есть огромный набор данных в CSV -формате, и для упрощения обработки имеет смысл разделить его на несколько файлов. Это весьма распространенная практика для огромных наборов данных и довольно часто она называется «фрагментацией» или «шардингом».

При загрузке данных в Pandas вы можете создать единый DataFrame с помощью вертикальной пристыковки фрейма данных из каждого CSV -файла. Предположим, у нас есть 3 фрагмента по 5 миллионов строк в каждом. Тогда после вертикального стекинга наш итоговый фрейм данных будет содержать 15 миллионов строк.

В коде ниже показана вертикальная конкатенация DataFrame в Pandas.

Похожий результат можно получить при разделении набора данных не по строкам, а по столбцам. В таком случае, из каждого CSV -файла берется по нескольку столбцов со всеми строками. Это чем-то похоже на фрагментацию наборов данных по признакам. Далее выполняется горизонтальный стекинг для объединения столбцов/признаков.

Слияние

Слияние — это более сложный и мощный тип объединения DataFrame в стиле SQL . Фреймы данных объединяются по какому-то общему атрибуту.

Допустим, у вас есть два DataFrame с описанием YouTube-канала. Один из фреймов — это список ID пользователей и общее количество времени, которое каждый пользователь провел на канале. Другой фрейм содержит тот же список с ID и количество просмотренных роликов по каждому пользователю. Благодаря слиянию мы сможем объединить два фрейма данных в один по ID пользователя, а затем добавим туда единой строкой ID, затраченное время и количество просмотренных роликов.

Слияние двух DataFrame в Pandas делается через функцию merge . Пример ее использования можно найти ниже. Параметры left и right задают два DataFrame для объединения, а в on отмечается столбец для сопоставления данных.

Чтобы еще качественнее имитировать SQL -объединение, воспользуйтесь параметром how . Он позволяет выбрать тип SQL -объединения: внутреннее, внешнее, слева или справа. Подробнее об SQL -объединениях читайте на W3Schools.

(3) Изменение формы DataFrame

Существует несколько способов изменения формы и структуры фреймов данных в Pandas. От простых и легких до мощных и сложных. Давайте рассмотрим три наиболее популярные разновидности. Во всех примерах мы будем работать с набором данных о супергероях.

Транспонирование

Простейший способ. Здесь мы заменяем строки DataFrame на столбцы. Если у вас есть 5 000 строк и 10 столбцов, то после транспонирования вы получите 10 строк и 5 000 столбцов.

Groupby

Основное назначение Groupby — это разделение фреймов данных на части по определенным ключам. После разделения DataFrame вы сможете пройтись циклом по каждой из частей или выполнить дополнительные действия.

Например, в коде ниже мы создали фрейм данных по игрокам с их стажем ( Years ) и количеством очков ( Points ). Затем с помощью groupby мы разделили DataFrame на несколько частей по полю «игрок» ( Player ). Таким образом, каждый игрок оказался в собственной группе, показывающей, сколько очков данный игрок набрал за каждый год активности.

Стекинг

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

Лучше всего все это показано в коде ниже.

(4) Работа с данными о дате и времени

Библиотека Datetime — это неотъемлемая часть Python. Всякий раз, встретив данные о дате или времени, вы обращаетесь к Datetime . К счастью для нас, Pandas придумала собственные возможности для использования объектов Datetime .

Давайте рассмотрим их на примере. В коде ниже мы создаем DataFrame с 4 столбцами (день, месяц, год, нужные данные), а затем сортируем их по году и месяцу. Как видите, получается слишком громоздко: для хранения данных используется целых 3 столбца, тогда как по факту календарная дата — это всего лишь одно значение.

Навести здесь порядок нам поможет datetime .

Pandas придумала отличную функцию to_datetime() , которая сжимает несколько столбцов DataFrame и преобразует их в единый объект Datetime . Сразу при задании нужного формата нам становятся доступны все гибкие возможности библиотеки Datetime .

Чтобы воспользоваться функцией to_datetime() , передадим ей все данные о дате из соответствующих столбцов ( Day , Month , Year ). После преобразования этих данных в формат Datetime , остальные столбцы нам больше не потребуются. Если хотите, можете от них избавиться. Вот, как все работает:

(5) Классификация элементов по группам

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

Взгляните на код ниже. Здесь приводится список продуктов, которые хотелось бы классифицировать:

Здесь мы выносим наш список в Series и создаем словарь с нужной нам классификацией Protein или Carbs . Это простейший пример. Но если бы эта Series была достаточно крупной (например, в 1 000 000 элементов длиной), то прохождение по ней циклом оказалось бы совершенно не разумным решением.

В таком случае, вместо обычного цикла for , лучше написать отдельную функцию, которая будет использовать встроенную Pandas-функцию map() для оптимизации процесса. В коде ниже все подробно расписано.

В этой функции мы проходимся циклом по всему словарю и создаем новый словарь, в котором ключами служат все вариации элементов из Series , а значениями являются признаки Protein или Carbs . Далее мы просто применяем встроенную функцию map() и классифицируем все значения из Series .

Вот, что у нас получается:

Заключение

Вот и все. Теперь вы узнали о 5 продвинутых возможностях Pandas и вариантах их применения.

Rukovodstvo

статьи и идеи для разработчиков программного обеспечения и веб-разработчиков.

Как объединить DataFrames в Pandas — merge (), join (), append (), concat () и update ()

Введение Pandas предоставляет огромный набор методов и функций для управления данными, включая слияние DataFrames. Слияние DataFrames позволяет вам создавать новый DataFrame без изменения исходного источника данных или изменения исходного источника данных. Если вы знакомы с SQL или аналогичным типом табличных данных, вы, вероятно, знакомы с термином соединение, которое означает объединение DataFrames для формирования нового DataFrame. Если вы новичок, может быть трудно полностью понять типы соединения (в

Время чтения: 14 мин.

Вступление

Pandas предоставляет огромный набор методов и функций для управления данными, включая слияние DataFrames. Слияние DataFrames позволяет вам создавать новый DataFrame без изменения исходного источника данных или изменения исходного источника данных.

Если вы знакомы с SQL или аналогичным типом табличных данных, вы, вероятно, знакомы с термином join , что означает объединение DataFrames для формирования нового DataFrame. Если вы новичок, может быть трудно полностью понять типы соединения ( внутреннее, внешнее, левое, правое ). В этом руководстве мы рассмотрим типы соединений с примерами.

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

В этом руководстве мы используем Pandas версии 1.1.4 и NumPy версии 1.19.4 .

Для вашего удобства вот содержание:

  • Объединить фреймы данных с помощью merge ()
  • Объединить фреймы данных с помощью join ()
  • Объединить фреймы данных с помощью append ()
  • Объединить фреймы данных с помощью concat ()
  • Объединение фреймов данных с помощью comb_first () и update ()

Объединить фреймы данных с помощью merge ()

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

df1 будет включать наш воображаемый список пользователей с именами, адресами электронной почты и идентификаторами.

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

Чтобы смоделировать этот сценарий, мы сделаем то же самое, создав df2 с URL-адресами изображений и идентификаторами пользователей:

Вот как выглядят наши DataFrames:

Давайте объединим эти DataFrames с функцией merge() . Во-первых, взгляните на все параметры, которые может принимать эта функция:

Большинство этих параметров имеют значения по умолчанию, за исключением левого и правого . Эти два параметра являются именами DataFrames, которые мы будем объединять. Сама функция вернет новый DataFrame, который мы сохраним в переменной df3_merged

Введите следующий код в оболочку Python:

Поскольку оба наших DataFrames имеют столбец user_id с одинаковым именем, merge() автоматически объединяет две таблицы, соответствующие этому ключу. Если бы у нас было два столбца с разными именами, мы могли бы использовать left_on=’left_column_name’ и right_on=’right_column_name’ чтобы явно указать ключи для обоих DataFrames.

df3_merged чтобы увидеть ее содержимое:

Вы заметите, что df3_merged имеет только 5 строк, в то время как исходный df1 имел 7. Почему?

Когда значение по умолчанию для how установлено на inner , новый DataFrame создается из пересечения левого и правого DataFrame. Следовательно, если user_id отсутствует в одной из таблиц, его не будет в объединенном DataFrame.

Это останется верным, даже если поменять местами левую и правую строки:

Пользователи с идентификаторами ‘id006’ и ‘id007’ не являются частью объединенных DataFrames, поскольку они не пересекаются в обеих таблицах.

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

Как? Используя merge() , мы можем передать аргумент ‘left’ how :

При левом соединении мы включили все элементы левого DataFrame ( df1 ) и каждый элемент правого DataFrame ( df2 ). Выполнение приведенного выше кода отобразит следующее:

Ячейки, которые не имеют совпадающих значений с левым DataFrame, заполняются NaN .

Почему бы нам не попробовать правильное соединение? Создайте следующий объединенный DataFrame:

Как вы могли ожидать, правое соединение вернет каждое значение из левого DataFrame, которое соответствует правому DataFrame:

Поскольку каждая строка в df2 имеет значение в df1 , в этом случае это right соединение аналогично inner

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

Имейте в виду, что наш левый DataFrame — это df2 а правый DataFrame — это df1 . Использование how=’outer’ объединяет DataFrames, совпадающие по ключу, но также включает значения, которые отсутствуют или не совпадают.

Мы также добавили indicator и установили для него значение True чтобы Pandas добавил дополнительный столбец _merge в конец нашего DataFrame. Этот столбец сообщает нам, была ли найдена строка в левом, правом или обоих фреймах данных.

df_left выглядит так:

Однако в df_outer есть такие данные:

Обратите внимание, что в df_outer DataFrame id006 и id007 существует только в правом DataFrame (в данном случае это df1 ). Если мы попытаемся сравнить левое и внешнее соединения, не меняя местами, мы получим одинаковые результаты для них обоих.

Объединить фреймы данных с помощью join ()

В отличие от merge() который является методом экземпляра Pandas, join() является методом самого DataFrame. Это означает, что мы можем использовать его как статический метод в DataFrame: DataFrame.join(other, on=None, how=’left’, lsuffix=», rsuffix=», sort=False) .

DataFrame, из которого мы вызываем join() будет нашим левым DataFrame. DataFrame в other аргументе будет нашим правильным DataFrame.

Параметр on может принимать один или несколько [‘key1’, ‘key2’ . ] ) для определения соответствующего ключа, в то время how параметр how принимает один из аргументов дескриптора (левый, правый, внешний, внутренний), и он по умолчанию установлено left

Попробуем присоединить df2 к df1 :

Как и функция merge() join() автоматически пытается сопоставить ключи (столбцы) с тем же именем. В нашем случае это ключ user_id

Приведенный выше код распечатывает это:

Вы, наверное, заметили «повторяющийся столбец» под названием user_id_right . Если вы не хотите отображать этот столбец, вы можете установить user_id в качестве индекса для обоих столбцов, чтобы он присоединялся без суффикса:

Таким образом мы избавляемся от user_id и вместо этого устанавливаем его в качестве столбца индекса. Это дает нам более чистый результирующий DataFrame:

Объединить фреймы данных с помощью append ()

Как указывает официальная документация Pandas, поскольку concat() и append() возвращают новые копии DataFrames, чрезмерное использование этих методов может повлиять на производительность вашей программы.

Добавление очень полезно, когда вы хотите объединить два DataFrames только по оси строк. Это означает, что вместо сопоставления данных в их столбцах нам нужен новый DataFrame, содержащий все строки 2 DataFrame.

Давайте df2 к df1 и распечатаем результат:

Использование append() не приведет к сопоставлению DataFrames ни по каким ключам. Он просто добавит другой DataFrame к первому и вернет его копию. Если формы DataFrames не совпадают, Pandas заменит все несовпадающие ячейки на NaN.

Результат для добавления двух DataFrames выглядит следующим образом:

Большинство пользователей выбирают concat() append() поскольку он также предоставляет параметр сопоставления ключей и оси.

Объединить фреймы данных с помощью concat ()

Конкатенация немного более гибкая по сравнению с merge() и join() поскольку она позволяет нам комбинировать DataFrames по вертикали (по строкам) или по горизонтали (по столбцам).

Компромисс заключается в том, что любые несоответствующие данные будут отброшены. Вот полная функция с параметрами:

Вот наиболее часто используемые параметры функции concat() :

  • objs — это список объектов DataFrame ([df1, df2, . ]) для объединения
  • axis определяет направление конкатенации, 0 для строк и 1 для столбцов
  • join может быть inner (пересечение) или outer (объединение)
  • ignore_index по умолчанию установлен на False что позволяет значениям индекса оставаться такими, какими они были в исходных DataFrames, может привести к дублированию значений индекса. Если установлено значение True , он будет игнорировать исходные значения и повторно назначать значения индекса в последовательном порядке.
  • keys позволяет нам построить иерархический индекс. Подумайте об этом как о другом уровне индекса, который добавлен слева от DataFrame, который помогает нам различать индексы, когда значения не уникальны.

Давайте создадим новый DataFrame с теми же типами столбцов с df2 , но этот включает image_url для id006 и id007 :

Чтобы объединить df2 и df2_addition строкам, мы можем передать их в списке в качестве objs и присвоить полученный DataFrame новой переменной:

Мы успешно заполнили недостающие значения:

Однако обратите внимание на индексы в крайнем левом столбце. Индексы 0 и 1 повторяются. Чтобы получить совершенно новые и уникальные значения индекса, мы передаем True параметру ignore_index

Теперь наш df_row_concat имеет уникальные значения индекса:

Как мы упоминали ранее, конкатенация может работать как по горизонтали, так и по вертикали. Чтобы объединить два DataFrames вместе по столбцам, нам нужно будет изменить значение axis 0 по 1 :

Вы заметите, что это не работает как слияние, сопоставление двух таблиц по ключу:

Если бы в нашем правом DataFrame даже не было user_id , эта конкатенация все равно вернула бы тот же результат. Функция concat() склеивает два DataFrames вместе, принимая во внимание значения индексов DataFrames и форму таблицы.

Он не выполняет сопоставление ключей, например merge() или join() . Попробуйте разные комбинации конкатенации, изменив join чтобы увидеть различия!

Читать:
Системный таймер на материнской плате что это

Объединение фреймов данных с помощью comb_first () и update ()

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

В этом примере мы импортируем NumPy, чтобы использовать значения NaN Если вы установили Pandas с помощью pip , NumPy уже должен быть установлен.

Введите следующий код в оболочку Python или файл сценария:

df_first df_first имеет 3 столбца и по 1 пропущенному значению в каждом из них:

В то время как df_second имеет только 2 столбца и одно отсутствующее значение в первом столбце:

Мы можем использовать df_second для исправления отсутствующих значений в df_first всеми соответствующими значениями:

Как упоминалось ранее, использование combine_first() заменит NaN только в порядке индексации и оставит все не пропущенные значения в первом DataFrame такими, какие они есть:

С другой стороны, если мы хотим перезаписать значения в df_first соответствующими значениями из df_second (независимо от того, являются они NaN или нет), мы бы использовали метод update() .

Давайте сначала добавим в наш код еще один DataFrame:

Форма (1, 3) — 1 строка и три столбца, не считая индекса:

Теперь давайте обновим df_first значениями из df_third :

Имейте в виду, что в отличие от combine_first() , update() не возвращает новый DataFrame. Он изменяет df_first на месте, изменяя соответствующие значения:

Для параметра overwrite update() по умолчанию установлено значение True Вот почему он изменяет все соответствующие значения, а не только значения NaN Мы можем изменить его на False чтобы заменить только значения NaN

Вот окончательное состояние нашего df_tictactoe df_tictactoe:

Мы не только успешно обновили значения, но и выиграли игру «Крестики-нолики»!

Заключение

Pandas предоставляет мощные инструменты для объединения DataFrames. Но бывает сложно решить, когда что использовать. Хотя в большинстве случаев функции merge() достаточно, в некоторых случаях вы можете использовать concat() для слияния по строкам, или использовать join() с суффиксами, или избавиться от отсутствующих значений с помощью combine_first() и update() . Вы даже можете добавлять строки данных с помощью append() .

Используйте ту функцию, которая вам удобна и лучше всего подходит для вашей задачи. Как эти функции помогут вам управлять данными в Pandas?

Combining Datasets: Concat and Append

Some of the most interesting studies of data come from combining different data sources. These operations can involve anything from very straightforward concatenation of two different datasets, to more complicated database-style joins and merges that correctly handle any overlaps between the datasets. Series and DataFrame s are built with this type of operation in mind, and Pandas includes functions and methods that make this sort of data wrangling fast and straightforward.

Here we’ll take a look at simple concatenation of Series and DataFrame s with the pd.concat function; later we’ll dive into more sophisticated in-memory merges and joins implemented in Pandas.

We begin with the standard imports:

For convenience, we’ll define this function which creates a DataFrame of a particular form that will be useful below:

A B C
0 A0 B0 C0
1 A1 B1 C1
2 A2 B2 C2

In addition, we’ll create a quick class that allows us to display multiple DataFrame s side by side. The code makes use of the special _repr_html_ method, which IPython uses to implement its rich object display:

The use of this will become clearer as we continue our discussion in the following section.

Recall: Concatenation of NumPy Arrays¶

Concatenation of Series and DataFrame objects is very similar to concatenation of Numpy arrays, which can be done via the np.concatenate function as discussed in The Basics of NumPy Arrays. Recall that with it, you can combine the contents of two or more arrays into a single array:

The first argument is a list or tuple of arrays to concatenate. Additionally, it takes an axis keyword that allows you to specify the axis along which the result will be concatenated:

Simple Concatenation with pd.concat ¶

Pandas has a function, pd.concat() , which has a similar syntax to np.concatenate but contains a number of options that we’ll discuss momentarily:

pd.concat() can be used for a simple concatenation of Series or DataFrame objects, just as np.concatenate() can be used for simple concatenations of arrays:

It also works to concatenate higher-dimensional objects, such as DataFrame s:

A B
1 A1 B1
2 A2 B2
A B
3 A3 B3
4 A4 B4
A B
1 A1 B1
2 A2 B2
3 A3 B3
4 A4 B4

By default, the concatenation takes place row-wise within the DataFrame (i.e., axis=0 ). Like np.concatenate , pd.concat allows specification of an axis along which concatenation will take place. Consider the following example:

A B
0 A0 B0
1 A1 B1
C D
0 C0 D0
1 C1 D1

pd.concat([df3, df4], axis=’col’)

A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1

We could have equivalently specified axis=1 ; here we’ve used the more intuitive axis=’col’ .

Duplicate indices¶

One important difference between np.concatenate and pd.concat is that Pandas concatenation preserves indices, even if the result will have duplicate indices! Consider this simple example:

A B
0 A0 B0
1 A1 B1
A B
0 A2 B2
1 A3 B3
A B
0 A0 B0
1 A1 B1
0 A2 B2
1 A3 B3

Notice the repeated indices in the result. While this is valid within DataFrame s, the outcome is often undesirable. pd.concat() gives us a few ways to handle it.

Catching the repeats as an error¶

If you’d like to simply verify that the indices in the result of pd.concat() do not overlap, you can specify the verify_integrity flag. With this set to True, the concatenation will raise an exception if there are duplicate indices. Here is an example, where for clarity we’ll catch and print the error message:

Ignoring the index¶

Sometimes the index itself does not matter, and you would prefer it to simply be ignored. This option can be specified using the ignore_index flag. With this set to true, the concatenation will create a new integer index for the resulting Series :

A B
0 A0 B0
1 A1 B1
A B
0 A2 B2
1 A3 B3

pd.concat([x, y], ignore_index=True)

A B
0 A0 B0
1 A1 B1
2 A2 B2
3 A3 B3
Adding MultiIndex keys¶

Another option is to use the keys option to specify a label for the data sources; the result will be a hierarchically indexed series containing the data:

A B
0 A0 B0
1 A1 B1
A B
0 A2 B2
1 A3 B3

pd.concat([x, y], keys=[‘x’, ‘y’])

A B
x 0 A0 B0
1 A1 B1
y 0 A2 B2
1 A3 B3

The result is a multiply indexed DataFrame , and we can use the tools discussed in Hierarchical Indexing to transform this data into the representation we’re interested in.

Concatenation with joins¶

In the simple examples we just looked at, we were mainly concatenating DataFrame s with shared column names. In practice, data from different sources might have different sets of column names, and pd.concat offers several options in this case. Consider the concatenation of the following two DataFrame s, which have some (but not all!) columns in common:

A B C
1 A1 B1 C1
2 A2 B2 C2
B C D
3 B3 C3 D3
4 B4 C4 D4
A B C D
1 A1 B1 C1 NaN
2 A2 B2 C2 NaN
3 NaN B3 C3 D3
4 NaN B4 C4 D4

By default, the entries for which no data is available are filled with NA values. To change this, we can specify one of several options for the join and join_axes parameters of the concatenate function. By default, the join is a union of the input columns ( join=’outer’ ), but we can change this to an intersection of the columns using join=’inner’ :

A B C
1 A1 B1 C1
2 A2 B2 C2
B C D
3 B3 C3 D3
4 B4 C4 D4

pd.concat([df5, df6], join=’inner’)

B C
1 B1 C1
2 B2 C2
3 B3 C3
4 B4 C4

Another option is to directly specify the index of the remaininig colums using the join_axes argument, which takes a list of index objects. Here we’ll specify that the returned columns should be the same as those of the first input:

A B C
1 A1 B1 C1
2 A2 B2 C2
B C D
3 B3 C3 D3
4 B4 C4 D4

pd.concat([df5, df6], join_axes=[df5.columns])

A B C
1 A1 B1 C1
2 A2 B2 C2
3 NaN B3 C3
4 NaN B4 C4

The combination of options of the pd.concat function allows a wide range of possible behaviors when joining two datasets; keep these in mind as you use these tools for your own data.

The append() method¶

Because direct array concatenation is so common, Series and DataFrame objects have an append method that can accomplish the same thing in fewer keystrokes. For example, rather than calling pd.concat([df1, df2]) , you can simply call df1.append(df2) :

A B
1 A1 B1
2 A2 B2
A B
3 A3 B3
4 A4 B4
A B
1 A1 B1
2 A2 B2
3 A3 B3
4 A4 B4

Keep in mind that unlike the append() and extend() methods of Python lists, the append() method in Pandas does not modify the original object–instead it creates a new object with the combined data. It also is not a very efficient method, because it involves creation of a new index and data buffer. Thus, if you plan to do multiple append operations, it is generally better to build a list of DataFrame s and pass them all at once to the concat() function.

Как соединить два датафрейма pandas

На завершающем уроке «Мастерской» по библиотеке Pandas мы научимся объединять датафреймы, применять lambda-функции и работать с большими файлами.

1. Объединнение датафреймов методами merge и concat

Объединение датафреймов — задача, которую приходится решать довольно часто. Чтобы научиться это делать, скачаем еще один файл в дополнение к данным по смертности, с которыми мы работали во время первых двух уроков. Скачаем файл на том же сайте Проекта по изучению глобального бремени болезней Института оценки показателей здоровья США (IHME GBD). Выберем те же показатели, что на первом занятии, только в графе measure выберем не deaths, а DALYs (Disability-Adjusted Life Years). Этот показатель означает, сколько лет здоровой и продуктивной жизни люди теряют из-за нетрудоспособности и ранней смерти от разных болезней. Его еще называют измерением разрыва между текущим состоянием здоровья людей и идеальной ситуацией, когда все население доживает до преклонного возраста, не страдая от болезней и инвалидности.

Чтобы не ждать, пока придут выбранные данные, можно скачать их по ссылкам:

Файл 1 — новый, с показателями DALY.

Файл 2 — прежний, с показателями смертности, deaths.

Импортируем библиотеку Pandas и загрузим оба файла.

Некоторые значения в столбцах в обоих датафреймах совпадают, а некоторые отличаются. Страна (location), пол (sex), возрасты (age), причины (cause), год (year) — одинаковые. А вот измерение (measure), а также числовые показатели val, upper и lower отличаются. В столбце metric тоже разные значения. Давайте объединим эти датафреймы, просто добавив новые значения (DALY, число потерянных лет из-за нетрудоспособности и ранней смерти от разных болезней) к тем данных по смертности, что у нас уже есть.

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

И объединим методом merge().

В аргументе on прописываем, в каких столбцах должны совпасть значения в обоих датафреймах. Аргумент how определяет, как именно объединить строки датафрейма:

inner — только общие, совпадающие в обоих датафреймах

outer — все строки из всех датафреймов, не важно, совпадающие или нет

left — только совпадающие строки плюс все строки из левого датафрейма

right — только совпадающие строки плюс все строки из правого датафрейма

Еще один метод объединения датафреймов — concat(). Чтобы его опробовать, разделим датафрейм на две части. В первой будут строки с первой до 50 000, во второй с 50 000 и до последней. А затем объединим их обратно методом concat(). Аргумент axis = 0 опять означает, что объединяем по строкам, а не по столбцам.

2.1. Добавление новых столбцов с помощью математических операций

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

Точно так же можно создать новый столбец на основе не одного, а нескольких других столбцов. Например, суммируя их. Попробуем суммировать столбцы death_val, death_upper, death_lower. В случае с нашими данными сумма этих показателей нам ничего не даст, это нужно просто для тренировки.

Появился новый столбец deaths_total. Точно так же можно суммировать с помощью сочетания методов loc и sum (вместо sum может быть и mean (среднее), median (медиана), std (стандартное отклонение), min, max и пр.).

Точно так же можно использовать iloc. Столбец deaths_val по счету 11-ый, deaths_lower — 13-ый.

Но сумма в столбце total_iloc отличается. Это потому, что метод iloc не включает правый край, то есть столбец номер 13 (deaths_lower) не посчитался. Нужно заменить 13 на 14, чтобы он тоже суммировался.

Удалим новые столбцы, чтобы не мешали.

2.2. Добавление новых столбцов с помощью функций

В Pandas очень удобно пользоваться короткими lambda-функциями, которые открывают много возможностей для анализа данных. Например, давайте создадим новый столбец, в котором будет True, если страна (location) входила в 2020 году в СНГ, и False, если нет. Представим, что нам зачем-то нужна эта информация. Для начала создадим список таких стран.

Затем создадим новый столбец и пропишем функцию, которая будет применяться к столбцу location и на его основе создавать нужный нам столбец: если страна входит в СНГ, напротив нее будет True, если нет, то False.

То же самое условие можно записать и короче.

Но lambda-функция подходит, только если функция короткая и простая. Если она сложнее, то нужно отдельно прописать ее и затем точно так же подставить для создания нового столбца. Пропишем ту же функцию, что и выше со странами СНГ, но отдельно. Точно также можно прописать любую более сложную функцию. Урок по функциям можно найти здесь.

3. Работа с большими файлами

В наших датафреймах от 90 от 257 тысяч строк, и обрабатывались они очень быстро. Но предположим, в файле не 257 тысяч, а миллионы строк. Такой файл будет долго грузиться, и работать с ним будет неудобно. Но Pandas позволяет легко работать и с большими файлами тоже. Для этого при загрузке есть параметр chunksize — или части, фрагмента, на которые мы хотим разбить файл, в затем работать с ними по отдельности, чтобы ускорить процесс.

Например, установим аргумент chunksize для нашего датафрейма в 50 000 строк. Это значит, что наш файл, в котором около 80 000 строк, будет разделен на две части. Попробуем его применить и выведем эти части на экран, чтобы посмотреть, как это выглядит.

С каждым из файлов теперь можно проделать какие-то операции по отдельности — выбрать нужные строки, посчитать параметры, удалить ненужное, а затем объединить их уже в более компактный датафрейм. Например, применим функцию groupby отдельно для каждой части и затем склеим их в одну. Чтобы это сделать, сначала нам нужно создать пустой датафрейм, а затем присоединять к нему результаты применения метода groupby для каждой части. Подробнее о методе groupby — во втором уроке. В получившемся датафрейме у нас будут не все строки из всех частей, а только нужные нам расчеты: как менялась средняя смертность и потерянные трудоспособные годы жизни от разных причин с годами.

Вот и всё, мы познакомились с основами библиотеки Pandas. Полученных знаний будет достаточно для того, чтобы начать анализировать данные. Конечно, мы рассказали не обо всех методах и нюансах, для этого есть подробные онлайн-курсы и книги. Более того, библиотека Pandas насколько хорошо изучена и популярна, что можно сформулировать буквально любой запрос: например, как разбить числовой столбец на интервалы, как объединить много файлов в один, как загрузить json, и в интернете будет множество вариантов того, как это сделать в Pandas.

Тетрадку с этого урока можно найти здесь. Если вы захотите задать вопросы и пообщаться, пишите нам в чат в Telegram. Если вам нравится «Мастерская», вы также можете оформить пожертвование. Ждем вас на следующих уроках!

Похожие статьи