Предположим, что проводится большое исследование основных биохимических показателей крови у пациентов, проходивших обследование в нескольких клиниках. Все пациенты должны отказаться в одном наборе данных — но исходно каждая клиника поставляет свой датасет. Индексом в каждом из них будет номер паспорта пациента, а параметры будут сходны — для всех пациентов, помимо имени и даты рождения, будут доступны концентрации альфа-амилазы, креатинина, общего белка и т.п. Они будут представлять собой столбцы таблиц — но в каждой таблице они будут расположены в разном порядке, потому что у разных лабораторий были разные бланки.
Объединять такие таблицы, например, в Excel, ужасно долго и муторно. К счастью, если их удалось загрузить в pandas в виде фреймов данных, есть решение одной командой. Если вы импортировали pandas как pd, то команда объединения будет выглядеть так:
pd.concat([df1, df2, df3,…])
Обратите внимание — перечень фреймов данных должен быть заключён в квадратные скобки внутри круглых. Вне квадратных скобок пишутся дополнительные аргументы для команды.
Как работает эта команда? Она выполнит операцию, называемую конкатенацией фреймов данных, то есть объединит данные по строкам, автоматически выровняв столбцы. Значения общего белка окажутся в одном столбце, значения креатинина — тоже в одном, несмотря на то что в исходных таблицах столбцы располагались по-разному.
А что будет, если один и тот же пациент проходит обследование в двух разных клиниках? Он будет в итоговом датасете дважды — и его индекс будет повторяться!
Но есть ещё одна проблема: у разных клиник разные перечни биохимических анализов. Какая-то клиника стандартно не выполняет исследование на мочевую кислоту, а какая-то стандартно не исследует липидный спектр. При конкатенации у части пациентов на месте соответствующих столбцов окажется пустое место, которое pandas автоматически заполнит значением NaN.
Теперь представим обратную ситуацию: есть большой набор данных по биохимическим анализам крови пациентов и такой же — по клиническим анализам крови. Эти данные надо тоже объединить в одну таблицу. Задача меняется на противоположную: надо объединить данные по столбцам и выровнять строки. В плане выравнивания строк возможны четыре варианта (см. картинку).
Прежде чем их рассматривать, договоримся о терминологии. В отличие от конкатенации, объединить сразу много фреймов данных не получится: это возможно сделать только попарно. Причём один фрейм будет первым (и будет как бы занимать левую позицию), а другой — вторым (и будет как бы находиться справа).
Множества пациентов в двух таблицах совпадать не будут: ведь кому-то выполнялся только биохимический анализ крови, а кому-то — только клинический, и лишь часть пациентов прошла оба обследования.
На этот случай метод join объекта DataFrame имеет аргумент how, для которого возможно четыре значения.
Команда
df1.join(df2, how=”outer”)
выполнит внешнее объединение, сохранив всех пациентов из обеих фреймов в новой таблице и заполнив пустые клетки значением NaN. Теперь понятно, что команда конкатенации по умолчанию выполняет тоже внешнее объединение, только применительно к столбцам. Математически операция внешнего объединения соответствует объединению множеств.
Чтобы итоговый фрейм содержал пересечение множеств пациентов — то есть тех пациентов, для которых имеются и биохимические, и клинические анализы — нужно выполнить внутреннее объединение:
df1.join(df2, how=”inner”)
Левое и правое объединение будут использовать множества пациентов из левого и правого фрейма, соответственно. Пустые клетки также будут заполнены значением NaN:
df1.join(df2, how=”left”)
df1.join(df2, how=”right”)
Нетрудно догадаться, что конкатенацию тоже можно выполнить в режиме внутреннего объединения. Для этого необходимо указать дополнительный параметр join=”inner” за пределами квадратных скобок (вот для чего они были нужны!):
pd.concat([df1, df2, df3,…], join=”inner”)
Подробнее все типы конкатенаций и объединений можно изучить по книге:
Хейдт М., Груздев А.В. Изучаем pandas / пер. с анг. А.В. Груздева. – М.: ДМК-Пресс, 2019. – 682 с.: ил.
У читателя мог возникнуть вопрос: раз некоторые методы объединения данных могут приводит к появлению пропущенных значений, то как же потом их заполнить? Ведь набор данных со множественными NaN непригоден для очень многих методов анализа. На этот случай существуют методы подстановки отсутствующих значений, или импутации (англ. imputation).
Больше полезной информации и образовательных ресурсов — в нашем телеграм-канале "Машинное обучение в биологии I OpenBio.edu".
vesper-bot
TL;DR такие же, как в SQL JOIN'ах.