如何用Python列表推导式替代嵌套循环并优化DataFrame匹配逻辑
问题描述
我需要处理两个DataFrame,通过球队名称匹配其所属城市(例如Philadelphia 76ers对应Philadelphia)。原嵌套循环代码存在匹配错误的问题,尝试用列表推导式重写时出现语法错误,希望优化代码并修正逻辑。
现有DataFrames
cities DataFrame:
city Population NBA 0 New York City 20153634 Knicks Nets 1 Los Angeles 13310447 Lakers Clippers 2 San Francisco Bay Area 6657982 Warriors 3 Chicago 9512999 Bulls[note 9] 4 Dallas–Fort Worth 7233323 Mavericks
nba_df DataFrame:
team W L W/L% GB PS/G PA/G SRS year League 0 Toronto Raptors 59 23 0.720 0.0 111.7 103.9 7.29 2018 NBA 1 Boston Celtics 55 27 0.671 4.0 104.0 100.4 3.23 2018 NBA 2 Philadelphia 76ers 52 30 0.634 7.0 109.8 105.3 4.30 2018 NBA 3 Cleveland Cavaliers 50 32 0.610 9.0 110.9 109.9 0.59 2018 NBA 4 Indiana Pacers 48 34 0.585 11.0 105.6 104.2 1.18 2018 NBA
解决方案
方法1:映射字典 + 自定义函数(高效易维护)
先清理脏数据并构建精准的球队-城市映射,再通过函数实现匹配逻辑:
import pandas as pd # 清理cities中的注释内容,去除无效字符 cities['NBA_clean'] = cities['NBA'].str.replace(r'\[.*?\]', '', regex=True).str.strip() # 构建球队昵称到城市的映射字典 team_city_map = {} for _, row in cities.iterrows(): city = row['city'] # 拆分同一城市的多支球队 nicknames = row['NBA_clean'].split() for nickname in nicknames: team_city_map[nickname] = city # 定义匹配函数:优先用映射匹配,无匹配则提取球队名称中的城市部分 def get_city(team_name): for nickname in team_city_map: if nickname in team_name: return team_city_map[nickname] # 提取球队名称的第一个单词作为城市(可根据实际规则调整) return team_name.split()[0] # 为nba_df添加城市列 nba_df['city'] = nba_df['team'].apply(get_city)
方法2:列表推导式实现(简洁高效)
用列表推导式结合生成器表达式,一行完成匹配逻辑:
import pandas as pd # 先构建映射字典(同方法1) cities['NBA_clean'] = cities['NBA'].str.replace(r'\[.*?\]', '', regex=True).str.strip() team_city_map = {} for _, row in cities.iterrows(): for nickname in row['NBA_clean'].split(): team_city_map[nickname] = row['city'] # 列表推导式生成城市列 nba_df['city'] = [ next((team_city_map[nick] for nick in team_city_map if nick in team), team.split()[0]) for team in nba_df['team'] ]
逻辑修正说明
- 清理脏数据:移除cities中NBA列的
[note 9]这类注释内容,避免干扰匹配。 - 精准映射:用字典存储球队昵称与城市的对应关系,彻底解决嵌套循环的错误匹配问题,同时提升匹配效率。
- 双重匹配逻辑:优先使用预定义映射匹配已知球队,对未收录的球队自动提取名称中的城市部分,覆盖更多场景。
- 语法错误修复:列表推导式中使用
next()函数处理生成器表达式,避免因无匹配项导致的语法异常。
最终结果
处理后的nba_df新增city列,示例输出:
team W L W/L% GB PS/G PA/G SRS year League city 0 Toronto Raptors 59 23 0.720 0.0 111.7 103.9 7.29 2018 NBA Toronto 1 Boston Celtics 55 27 0.671 4.0 104.0 100.4 3.23 2018 NBA Boston 2 Philadelphia 76ers 52 30 0.634 7.0 109.8 105.3 4.30 2018 NBA Philadelphia 3 Cleveland Cavaliers 50 32 0.610 9.0 110.9 109.9 0.59 2018 NBA Cleveland 4 Indiana Pacers 48 34 0.585 11.0 105.6 104.2 1.18 2018 NBA Indiana
内容的提问来源于stack exchange,提问作者milikest
相关产品推荐
相关产品推荐

