#python #pandas #merge #concatenation #vlookup
Вопрос:
Я хочу создать набор данных из двух df
с помощью id
. Проблема в том , что на втором df
, id
не находится в одном столбце. id
Значение может быть расположено в разных столбцах.
merged=pd.merge(df1, df2, left_on=['id','month','year'], right_on=['id_name','id_surname','id_first_name', month','year'], how="left")
Все id
переменные являются буквенно-цифровыми.
Но я получаю ошибку:
ValueError: len(right_on) must equal len(left_on)
В идеале я хотел бы проверить, находится ли id
он в одном из трех других столбцов ids
, и соответственно объединить их в этом столбце. Возможно, какая-то функция vlookup () (из excel), позволяющая искать значение ключа в диапазоне в массиве таблиц. Есть какие-нибудь идеи?
Комментарии:
1. Вы не можете присоединиться к другому количеству ключей. Вам нужно будет создать столбец для второго кадра данных, который будет содержать все необходимые идентификаторы. Вы также можете попытаться выполнить три соединения последовательно, по одному разу для каждого из столбцов «id_name», «id_surname», «id_first_name» второго df. Пожалуйста, предоставьте образец ваших кадров данных, чтобы я мог помочь больше 🙂
Ответ №1:
Предположим, у нас есть следующие два кадра данных:
import pandas as pd import numpy as np df1 = pd.DataFrame( { "id": [1, 2, 3], "month": ["Jan", "Mar", "Apr"], "year": ["2022", "2020", "2021"], "column_A": ["test", "test_", "test__"] } ) df2 = pd.DataFrame( { "id_name": [1, np.NaN, np.NaN], "id_surname": [np.NaN, 2, np.NaN], "id_first_name": [np.NaN, np.NaN, 3], "month": ["Jan", "Mar", "Apr"], "year": ["2022", "2020", "2021"], "column_B": ["check", "check_", "check__"] } )
Второй кадр данных будет:
id_name id_surname id_first_name month year column_B 0 1.0 NaN NaN Jan 2022 check 1 NaN 2.0 NaN Mar 2020 check_ 2 NaN NaN 3.0 Apr 2021 check__
Вы можете создать новый столбец id
для второго кадра данных, сохранив все значения, отличные от NaN, из трех столбцов id_name, id_surname, id_first_name
. Начиная с id_name
столбца и заполняя его NaN значениями, отличными id_surname
от Nan, а затем заполняя оставшиеся NaN значениями, отличными от NaN id_first_name
. Код для этого таков:
df2["id"] = df2["id_name"].fillna(df2["id_surname"]).fillna(df2["id_first_name"])
который создаст столбец id
для df2
:
id_name id_surname id_first_name month year column_B id 0 1.0 NaN NaN Jan 2022 check 1.0 1 NaN 2.0 NaN Mar 2020 check_ 2.0 2 NaN NaN 3.0 Apr 2021 check__ 3.0
Наконец, вы можете объединиться с помощью:
merged = pd.merge( df1, df2, left_on=["id", "month", "year"], right_on=["id", "month", "year"], how="left", )
и результат будет:
id month year column_A id_name id_surname id_first_name column_B 0 1 Jan 2022 test 1.0 NaN NaN check 1 2 Mar 2020 test_ NaN 2.0 NaN check_ 2 3 Apr 2021 test__ NaN NaN 3.0 check__
Комментарии:
1. Функция Pandas fillna была тем, что мне было нужно. Я даже не подумал об этом!