如何将df_training关键词映射至df_1_long并添加sector列
解决Pandas DataFrame匹配添加sector列的问题
数据与需求说明
现有两个Pandas DataFrame:
df_1_long = pd.DataFrame({ 'company_name': ['Company A', 'Company B', 'Company C'], 'company_country': ['USA', 'Poland', 'Canada'], 'keyword': ['holding', 'services', 'source'], 'value': [1,0,1] })
第二个DataFrame:
df_training = pd.DataFrame({ 'holding': [1, 0, 0], 'services': [0, 1, 0], 'source': [0, 0, 1], 'sector': ['Retail', 'Finance', 'Energy'] })
需求:当df_1_long中keyword对应的value为1,且df_training中对应关键词列的值为1时,为df_1_long添加对应的sector值;否则设为'no_sector',期望输出如下:
expected_output = pd.DataFrame({ 'company_name': ['Company A', 'Company B', 'Company C'], 'company_country': ['USA', 'Poland', 'Canada'], 'keyword': ['holding', 'services', 'source'], 'value': [1,0,1], 'sector': ['Retail', 'no_sector', 'Energy'] })
用户尝试的代码报错:
merged_df = pd.merge(df_1_long, df_training, left_on='keyword', right_on=df_training.columns[:-1]) df_1_long['sector'] = merged_df['sector'].where(merged_df['value'] == 1, np.nan)
正确实现方法
方法1:转换df_training格式后匹配
先把df_training转成长格式,让关键词作为单独一列,就能和df_1_long的keyword列直接匹配:
import pandas as pd # 将df_training转换为长格式,提取关键词与对应sector df_training_long = df_training.melt( id_vars='sector', value_vars=['holding', 'services', 'source'], var_name='keyword', value_name='match_flag' ) # 只保留匹配有效的行(值为1的项) df_training_long = df_training_long[df_training_long['match_flag'] == 1].drop('match_flag', axis=1) # 合并两个DataFrame merged = df_1_long.merge(df_training_long, on='keyword', how='left') # 根据条件设置sector值 df_1_long['sector'] = merged.apply( lambda x: x['sector'] if x['value'] == 1 else 'no_sector', axis=1 ) # 处理极端情况(比如value=1但无匹配的情况) df_1_long['sector'] = df_1_long['sector'].fillna('no_sector')
方法2:字典映射简化操作
如果df_training中每个关键词对应唯一sector(如示例结构),可以直接构建映射字典:
import pandas as pd # 构建keyword到sector的映射字典 sector_map = {} for idx, row in df_training.iterrows(): sector = row['sector'] # 找到当前行值为1的关键词列 keyword = row[row == 1].index[0] sector_map[keyword] = sector # 先映射sector,再结合value条件替换 df_1_long['sector'] = df_1_long['keyword'].map(sector_map) df_1_long['sector'] = df_1_long.apply( lambda x: x['sector'] if x['value'] == 1 else 'no_sector', axis=1 )
两种方法均可得到符合要求的输出。
内容的提问来源于stack exchange,提问作者user20999873
相关产品推荐
相关产品推荐

