Мне нужно присоединиться к приведенному ниже кадру данных на основе некоторого условия.
df1:
Id Value
[101,102,103] 10001
[101,102,104] 10000
[101,102,105] 10002
[101,107,105] 10003
df2:
Id Product_Name
[101,102,103,104] Shoe
[101,102,109,104] jeans
[101,105,102,108] make-up
[101,105,106,118] shirt
df_output
Id Value Product_Name
[101,102,103] 10001 Shoe -- Every value present in df2.Id list
[101,102,104] 10000 Jeans -- Every value present in df2.Id list
[101,102,105] 10002 Make-Up -- Every value present in df2.Id list
[101,107,105] 10003 NaN -- Not Every Value matches in df2.Id list.
Мне нужно объединить два кадра данных df1, df2 на основе столбца Id, но каждый элемент должен быть в списке df.Id, когда мы считаем его совпадением.
Python Code:
import pandas as pd
df_output = pd.merge(df1, df2, on='Id', how='left')
🤔 А знаете ли вы, что...
Python активно используется в научных и инженерных вычислениях.
Хотя это не очень эффективное решение, вы можете использовать некоторые set
для решения этой проблемы.
matches = df1["Id"].apply(set) <= df2["Id"].apply(set)
out = df1.copy()
out.loc[matches, df2.columns.difference(["Id"])] = df2
print(out)
Id Value Product_Name
0 [101, 102, 103] 10001 Shoe
1 [101, 102, 104] 10000 jeans
2 [101, 102, 105] 10002 make-up
3 [101, 107, 105] 10003 NaN
В приведенном выше фрагменте:
matches = df1["Id"].apply(set) <= df2["Id"].apply(set)
возвращает логическое значение Series
, которое имеет значение True, если содержимое каждой строки в df1['Id'] находится в соответствующей строке в df2['Id'], и False в противном случае.merge
мы можем просто выровнять 2 кадра данных по вышеупомянутому логическому Series
Если вы хотите протестировать идентификаторы друг против друга в обоих фреймах данных, вы можете взять декартово произведение обоих фреймов данных, отфильтровать его до внутреннего соединения с помощью заданных критериев, а затем добавить обратно все отсутствующие левые ключи соединения.
out = (
pd.merge(df1, df2, how = "cross")
.loc[lambda df: df["Id_x"].map(set) <= df["Id_y"].map(set)]
.pipe(
lambda df: df.append(
df1.loc[~df1["Id"].isin(df["Id_x"])].rename(columns = {"Id": "Id_x"})
)
)
.reset_index(drop=True)
)
print(out)
Id_x Value Id_y Product_Name
0 [101, 102, 103] 10001 [101, 102, 103, 104] Shoe
1 [101, 102, 104] 10000 [101, 102, 103, 104] Shoe
2 [101, 102, 104] 10000 [101, 102, 109, 104] jeans
3 [101, 102, 105] 10002 [101, 105, 102, 108] make-up
4 [101, 107, 105] 10003 NaN NaN