如何修改Pandas函数实现df1与df2列的严格左前缀匹配
问题描述
现有两个DataFrame:
import pandas as pd df1=pd.DataFrame({'name': ['123456789', '5486544546', '65464564', '478615454']}) df2=pd.DataFrame({'num': ['12345', '54865', '5464','7861']})
需要修改以下函数,实现df1的name列值以df2的num列值为严格左前缀的匹配(当前函数会匹配任意位置的子串):
df2['yes/no'] = df2['num'].apply(lambda x: df1['name'][df1['name'].astype(str).str.contains(str(x))].values[0] if len(df1['name'][df1['name'].astype(str).str.contains(str(x))].values)> 0 else 0)
期望结果
| num | yes/no |
|---|---|
| 12345 | 123456789 |
| 54865 | 5486544546 |
| 5464 | 0 |
| 7861 | 0 |
当前错误结果
| num | yes/no |
|---|---|
| 12345 | 123456789 |
| 54865 | 5486544546 |
| 5464 | 65464564 |
| 7861 | 478615454 |
解决方案
核心修改是把匹配任意子串的str.contains()替换为匹配左前缀的str.startswith(),同时优化代码避免重复计算:
# 提前将df1的name转为字符串,避免重复转换 df1['name_str'] = df1['name'].astype(str) df2['yes/no'] = df2['num'].apply( lambda x: df1.loc[df1['name_str'].str.startswith(str(x)), 'name'].values[0] if len(df1.loc[df1['name_str'].str.startswith(str(x)), 'name']) > 0 else 0 )
说明
str.startswith():该方法专门判断字符串是否以指定前缀开头,完全符合"严格左前缀匹配"的需求,替代原来的str.contains()(会匹配任意位置的子串)。- 提前转换字符串:把df1的
name列转为字符串并存储为新列name_str,避免在循环中重复执行类型转换,提升代码效率。 df.loc索引:相比直接列索引,df.loc的写法更清晰,可读性更强。
执行上述代码后,即可得到期望的匹配结果。
内容的提问来源于stack exchange,提问作者Aizhan Askhatova
相关产品推荐
相关产品推荐

