You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Pandas找出两个DataFrame中属性匹配最多的姓名与用户名?

解决思路:对比两个DataFrame的属性匹配度

问题背景

有两个Pandas DataFrame:
第一个df_names结构如下:

name                           attributes
0                 John  [ABC, DEF, GHI, JKL, MNO, PQR, STU]
1                 Mike  [EUD, DBS, QMD, ABC, GHI]
2                 Jane  [JKL, EJD, MDE, MNO, DEF, ABC]
3                Kevin  [FHE, EUD, GHI, MNO, ABC, AUE, HSG, PEO]
4             Stefanie  [STU, EJD, DUE]

第二个df_usernames结构如下:

username                                 attr
0           username_1  [DHD, EOA, AUE, CHE, ABC, PQR, QJF]
1           username_2  [ABC, EKR, ADT, GHI, JKL, EJD, MNO, MDE]
2           username_3  [DSB, AOD, DEF, MNO, DEF, ABC, TAE]
3           username_4  [DJH, EUD, GHI, MNO, ABC, FHE]
4           username_5  [CHQ, ELT, ABC, DEF, GHI]

需要找出name和username中共享属性数量最多的组合,比如示例里username_4和Kevin有5个匹配属性。

可行解决思路

方法1:集合交集+笛卡尔积全组合对比

先把属性列表转成集合(自动去重,重复属性不影响匹配计数),然后生成两个DataFrame的全组合,计算每组的交集长度:

import pandas as pd

# 构造示例数据
df_names = pd.DataFrame({
    'name': ['John', 'Mike', 'Jane', 'Kevin', 'Stefanie'],
    'attributes': [
        ['ABC', 'DEF', 'GHI', 'JKL', 'MNO', 'PQR', 'STU'],
        ['EUD', 'DBS', 'QMD', 'ABC', 'GHI'],
        ['JKL', 'EJD', 'MDE', 'MNO', 'DEF', 'ABC'],
        ['FHE', 'EUD', 'GHI', 'MNO', 'ABC', 'AUE', 'HSG', 'PEO'],
        ['STU', 'EJD', 'DUE']
    ]
})

df_usernames = pd.DataFrame({
    'username': ['username_1', 'username_2', 'username_3', 'username_4', 'username_5'],
    'attr': [
        ['DHD', 'EOA', 'AUE', 'CHE', 'ABC', 'PQR', 'QJF'],
        ['ABC', 'EKR', 'ADT', 'GHI', 'JKL', 'EJD', 'MNO', 'MDE'],
        ['DSB', 'AOD', 'DEF', 'MNO', 'DEF', 'ABC', 'TAE'],
        ['DJH', 'EUD', 'GHI', 'MNO', 'ABC', 'FHE'],
        ['CHQ', 'ELT', 'ABC', 'DEF', 'GHI']
    ]
})

# 将属性列转为集合,方便计算交集
df_names['attr_set'] = df_names['attributes'].apply(set)
df_usernames['attr_set'] = df_usernames['attr'].apply(set)

# 生成全组合(笛卡尔积)
cross_df = df_names.assign(key=1).merge(df_usernames.assign(key=1), on='key').drop('key', axis=1)

# 计算每组共享属性的数量
cross_df['shared_attr_count'] = cross_df.apply(
    lambda row: len(row['attr_set_x'] & row['attr_set_y']),
    axis=1
)

# 筛选出共享数量最多的组合
max_shared = cross_df['shared_attr_count'].max()
result = cross_df[cross_df['shared_attr_count'] == max_shared][['name', 'username', 'shared_attr_count']]

print(result)

运行后会直接输出所有共享属性数量最多的name和username组合。

方法2:内存优化版(大数据量适用)

如果两个DataFrame行数较多,笛卡尔积会占用大量内存,可以改用循环遍历组合,同时记录最大值:

import itertools

max_count = 0
best_pairs = []

# 遍历所有name和username的组合
for name_row, user_row in itertools.product(df_names.itertuples(), df_usernames.itertuples()):
    name_attr = set(name_row.attributes)
    user_attr = set(user_row.attr)
    shared_num = len(name_attr & user_attr)
    if shared_num > max_count:
        max_count = shared_num
        best_pairs = [(name_row.name, user_row.username, shared_num)]
    elif shared_num == max_count:
        best_pairs.append((name_row.name, user_row.username, shared_num))

# 输出结果
print(f"最大共享属性数:{max_count}")
print("最佳匹配组合:")
for pair in best_pairs:
    print(f"{pair[0]} 和 {pair[1]},共享{pair[2]}个属性")

处理字符串形式的列表

如果你的DataFrame中attributes或attr列是字符串格式的列表(比如"[ABC, DEF, GHI]"而非真正的Python列表),需要先解析成列表:

import ast
# 将字符串形式的列表转为Python列表
df_names['attributes'] = df_names['attributes'].apply(ast.literal_eval)
df_usernames['attr'] = df_usernames['attr'].apply(ast.literal_eval)

用ast.literal_eval可以安全地将字符串解析为对应的Python对象,之后再按上述方法处理即可。

内容的提问来源于stack exchange,提问作者Jelz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 06:35:48