在Pandas单元格列表中匹配编号,关联另一DataFrame对应字符串
解决方案:将编号映射为对应属性名称并合并到同一单元格
首先咱们把核心需求理清楚:把train_df中每个单元格的编号列表,替换成labels_df里对应的属性名称,放在同一行的新列中。最高效的实现方式是先建立「编号→属性名」的映射字典,再批量处理train_df的列,比逐行循环或者查找要快得多。
步骤1:构建编号与属性名的映射字典
先从labels_df生成一个字典,用编号做键,对应的属性名称做值。假设labels_df的编号列名为attribute_id_num,属性名列名为attribute_name(你可以根据修改后的第一列名称调整):
# 构建映射字典,这是最关键的一步,后续查找速度极快 id_to_name = labels_df.set_index('attribute_id_num')['attribute_name'].to_dict()
步骤2:预处理train_df的编号列
如果你的attribute_ids列是字符串格式(比如"147,616,813"),需要先分割成整数列表;如果已经是列表格式,可以跳过这一步:
# 分割字符串并转换为整数列表 train_df['attribute_ids'] = train_df['attribute_ids'].str.split(',').apply(lambda x: [int(num) for num in x])
步骤3:批量映射生成新列
用apply函数遍历每个编号列表,把每个编号替换成对应的属性名称,你可以根据需求选择两种格式:
# 方案1:保留列表格式(每个单元格是属性名称的列表) train_df['attribute_names'] = train_df['attribute_ids'].apply(lambda ids: [id_to_name[id] for id in ids]) # 方案2:合并为逗号分隔的字符串(更适合单元格展示) train_df['attribute_names'] = train_df['attribute_ids'].apply(lambda ids: ','.join([id_to_name[id] for id in ids]))
可选:处理异常情况
如果train_df里存在labels_df中没有的编号,可以用dict.get()添加默认值,避免报错:
train_df['attribute_names'] = train_df['attribute_ids'].apply( lambda ids: ','.join([id_to_name.get(id, 'Unknown') for id in ids]) )
完整示例代码
假设你的数据加载逻辑是这样的:
import pandas as pd # 加载CSV数据 train_df = pd.read_csv('train.csv') labels_df = pd.read_csv('labels.csv') # (如果需要)修改labels_df的第一列名称,比如改成attribute_id_num labels_df.rename(columns={labels_df.columns[0]: 'attribute_id_num'}, inplace=True) # 构建映射字典 id_to_name = labels_df.set_index('attribute_id_num')['attribute_name'].to_dict() # 预处理编号列(如果是字符串格式) train_df['attribute_ids'] = train_df['attribute_ids'].str.split(',').apply(lambda x: [int(num) for num in x]) # 生成属性名称列 train_df['attribute_names'] = train_df['attribute_ids'].apply(lambda ids: ','.join([id_to_name[id] for id in ids]))
为什么你之前的尝试没成功?
- 你用
df2.iloc[i]的逻辑有误:iteritems()返回的是(索引, 值)的元组,i是元组不是整数索引,所以会报错; - Danny提供的代码是反向查找(用属性名找编号),和你的需求正好相反,所以方向偏了。
内容的提问来源于stack exchange,提问作者Matan
相关产品推荐
相关产品推荐

