如何将元组字典映射到DataFrame多列以重编号PDB残基
解决PDB DataFrame残基编号与插入码的映射问题
我来帮你搞定这个PDB残基编号映射的问题!你的思路方向其实没错,只是在多列组合成字典键和映射后的值拆分这两步需要调整细节,下面是具体的实现方案:
步骤1:准备数据
先把你给出的示例数据和映射字典初始化好:
import pandas as pd # 初始化原DataFrame d = {'ATOM' : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], 'residue_number' : [2, 2, 2, 3, 3, 3, 3, 3, 3, 5, 5, 5], 'insertion' : ['', '', '', '', '', '', 'A', 'A', 'A', '', '', '']} df = pd.DataFrame(data=d) # 初始化映射字典 my_dict = {(2,): 1, (3,): 2, (3, 'A') : 3, (5, ) : (4, 'A') }
步骤2:生成匹配字典的键元组
核心是把residue_number和insertion两列组合成与字典键格式完全一致的元组:
- 当
insertion为空字符串时,生成单元素元组(比如(2,)) - 当
insertion有值时,生成双元素元组(比如(3, 'A'))
代码实现:
# 生成用于匹配字典的键元组 df['key'] = df.apply( lambda row: (row['residue_number'],) if row['insertion'] == '' else (row['residue_number'], row['insertion']), axis=1 )
步骤3:根据字典映射获取新值
用生成的键元组去匹配字典,得到对应的新编号/插入码组合:
# 映射得到新的编号组合 df['new_values'] = df['key'].map(my_dict)
步骤4:拆分映射结果为目标列
映射后的结果有两种类型:单个整数(对应插入码为空)或双元素元组(对应有插入码),我们需要把它们拆分成新的residue_number和insertion列:
# 拆分结果为目标列 df[['new_residue', 'new_insertion']] = df['new_values'].apply( lambda x: pd.Series([x, '']) if isinstance(x, int) else pd.Series(x) )
步骤5:整理最终DataFrame
替换原列并清理临时列,调整回你需要的列顺序:
# 替换原列并清理临时列 df = df.drop(columns=['key', 'new_values', 'residue_number', 'insertion']) df = df.rename(columns={'new_residue': 'residue_number', 'new_insertion': 'insertion'}) # 调整列顺序与原表一致 df = df[['ATOM', 'residue_number', 'insertion']]
最终输出
运行完上述代码后,你会得到期望的结果:
ATOM residue_number insertion 0 1 1 1 2 1 2 3 1 3 4 2 4 5 2 5 6 2 6 7 3 7 8 3 8 9 3 9 10 4 A 10 11 4 A 11 12 4 A
思路总结
你之前尝试的mapping和multiindex方向是对的,只是没精准匹配字典的键格式,也没处理映射后的值类型差异。这个方案的核心是:
- 把两列数据转换成与字典键完全一致的元组格式
- 针对映射结果的不同类型(整数/元组)做拆分处理
内容的提问来源于stack exchange,提问作者Drewaight
相关产品推荐
相关产品推荐

