计算排名并连接 2 个数据框

问题描述 投票:0回答:1

假设我有 2 个数据框,其中有 3 个公共标识列。

dataframe1

id1  id2  id3  value1 value2    value3
1001 9001 3001 blue   square    true
1005 9001 3001 yellow circle    false
1009 2001 3001 black  rectangle true
1010 9001 5001 blue   star      false

dataframe2
id1  id2  id3  valuex valuey valuez
1001 9001 3001 1000   2.5    5
1001 null null 200    1.0    3
null 9001 null 200    5.4    0
null 9001 3001 1000   3.5    6
1001 9001 null 1001   4.5    7
1001 null 3001 1001   4.5    7

input, intermediate output & final output

在此示例中,我可以将 dataframe1 中的一行与 dataframe2 中的多行进行匹配。我想根据匹配的列分配排名,并使用最高排名加入。

我想根据排名加入dataframe1和dataframe2,在id列id1、id2和id3之间,如果3列匹配,我想考虑最高排名并加入并忽略与id1和id2或id2和id3等匹配的其他行.,如果 3 列不匹配,我想考虑 2 个 id 列匹配的行并确定优先级 - 比如说,如果有 2 行有 2 个 id 匹配,如 id1 和 id2、id2 和 id3,我想优先考虑 id2 和 id3 (意味着会获得更高的排名)。

我该怎么办?我更喜欢使用函数来计算排名,以便我可以实现复杂的逻辑。

python pandas dataframe
1个回答
0
投票
import pandas as pd

df1 = pd.DataFrame(
    {
        "id1": [1001, 1005, 1009, 1010],
        "id2": [9001, 9001, 2001, 9001],
        "id3": [3001, 3001, 3001, 5001],
        "value1": ["blue", "yellow", "black", "blue"],
        "value2": ["square", "circle", "rectangle", "star"],
        "value3": [True, False, True, False],
    }
)

df2 = pd.DataFrame(
    {
        "id1": [1001, 1001, None, None, 1001, 1001],
        "id2": [9001, None, 9001, 9001, 9001, None],
        "id3": [3001, None, None, 3001, None, 3001],
        "valuex": [1000, 200, 200, 1000, 1001, 1001],
        "valuey": [2.5, 1.0, 5.4, 3.5, 4.5, 4.5],
        "valuez": [5, 3, 0, 6, 7, 7],
    }
)

for col in ["id1", "id2", "id3"]:
    df2[col] = df2[col].astype("Int64")

df3 = pd.merge(df1, df2, how="cross")

df3["num_matches"] = df3.apply(
    lambda row: sum(
        [(row[f"id{i}_x"] == row[f"id{i}_y"]) is True for i in range(1, 4)]
    ),
    axis=1,
)

df3.sort_values("num_matches", ascending=False, inplace=True)
df3.drop_duplicates(
    subset=["id1_x", "id2_x", "id3_x"],
    keep="first",
    inplace=True,
)

print(df3)

产生

    id1_x  id2_x  id3_x  value1     value2  value3  id1_y  id2_y  id3_y  valuex  valuey  valuez  num_matches
0    1001   9001   3001    blue     square    True   1001   9001   3001    1000     2.5       5            3
6    1005   9001   3001  yellow     circle   False   1001   9001   3001    1000     2.5       5            2
15   1009   2001   3001   black  rectangle    True   <NA>   9001   3001    1000     3.5       6            1
22   1010   9001   5001    blue       star   False   1001   9001   <NA>    1001     4.5       7            1
© www.soinside.com 2019 - 2024. All rights reserved.