基于不同长度列表构建匹配目标序列的Pandas DataFrame
问题描述
我有两个字母列表List1与List2,二者长度不同,List2包含部分List1没有的元素。现有对应List1的Pandas DataFrame df,需构造新DataFrame df_new,使其NAME列匹配List2的完整序列:
- 若元素存在于List1,取df对应行数据;
- 若不存在,则填充默认值(ID递增、Val为0)。
示例信息
- List1:
F,L,D,G,H - List2:
F,L,B,L,D,G,A,H,C
输入DataFrame df
| ID | Val | NAME | |
|---|---|---|---|
| 0 | 1 | 122.58 | F |
| 1 | 4 | 123.11 | L |
| 2 | 5 | 120.54 | D |
| 3 | 6 | 108.57 | G |
| 4 | 8 | 119.83 | H |
期望输出DataFrame
| ID | Val | NAME | |
|---|---|---|---|
| 0 | 1 | 122.58 | F |
| 1 | 2 | 0 | L |
| 2 | 3 | 0 | B |
| 3 | 4 | 123.11 | L |
| 4 | 5 | 120.54 | D |
| 5 | 6 | 108.57 | G |
| 6 | 7 | 0 | A |
| 7 | 8 | 119.83 | H |
| 8 | 9 | 0 | C |
尝试的代码逻辑
if List2[i]== List1[i]: new_row=df1.loc[i] elif List2[i]!=List1[i]: new_row=np.nan new_row_df=pd.DataFrame(new_row) df_new=pd.concat([df_new,new_row_df],ignore_index=True) df_new=df_new.sort_index().reset_index(drop=True)
解决方案
核心思路
- 将原df转换为以
NAME为键的映射字典,实现快速查找已存在元素的对应数据; - 遍历List2的每个元素,区分是否存在于原数据中,分别收集对应Val值;
- 统一生成连续递增的ID列,保证ID从1开始依次递增至List2的长度。
实现代码
import pandas as pd # 示例数据初始化 List1 = ['F', 'L', 'D', 'G', 'H'] List2 = ['F', 'L', 'B', 'L', 'D', 'G', 'A', 'H', 'C'] df = pd.DataFrame({ 'ID': [1, 4, 5, 6, 8], 'Val': [122.58, 123.11, 120.54, 108.57, 119.83], 'NAME': ['F', 'L', 'D', 'G', 'H'] }) # 构建NAME到Val的映射字典,用于快速查找 name_to_val = df.set_index('NAME')['Val'].to_dict() # 遍历List2,收集每行的Val和NAME数据 rows = [] for name in List2: rows.append({ 'Val': name_to_val.get(name, 0), 'NAME': name }) # 生成新DataFrame并设置连续ID df_new = pd.DataFrame(rows) df_new['ID'] = range(1, len(df_new) + 1) # 调整列顺序与原df一致 df_new = df_new[['ID', 'Val', 'NAME']] print(df_new)
代码说明
- 映射字典
name_to_val把查找操作的时间复杂度降到O(1),比循环遍历df更高效; - 使用
dict.get()方法可以简洁处理存在/不存在的两种情况,不存在时默认返回0; - 最后统一生成ID列,确保ID严格连续递增,完全符合需求。
内容的提问来源于stack exchange,提问作者tabi_k
相关产品推荐
相关产品推荐

