如何使用Pandas从DataFrame中提取POS、REF、ALT特定字段信息
解决DataFrame中REC格式字符串的字段提取问题
你的需求很明确——从每个单元格的REC格式内容里拆分出单个REC条目,再提取POS、REF、ALT字段,最终生成扁平化的DataFrame。之前的代码没成功主要是因为没处理多个REC的拆分,还有正则表达式的写法不对。我给你整理了一套可行的方案:
步骤拆解与完整代码
import pandas as pd # 你的原始数据 d = {'sample1':['REC(CHR=2,,POS=345432,,REF=G,ALT=A,,BAND=ARG), REC(CHR=2,,POS=245332,,REF=T,,ALT=GA,BAND=AA4T)', 'REC(CHR=4,,POS=23332,,REF=A,,ALT=G,BAND=C4T)','REC(CHR=8,,POS=3335332,,REF=G,,ALT=A,BAND=AA4T)'], 'sample2':['REC(CHR=2,,POS=34545432,,REF=T,,ALT=A,,BAND=ARG)','REC(CHR=4,,POS=45332,,REF=G,,ALT=GAGG,BAND=AA4SST)','REC(CHR=8,,POS=445332,,REF=G,,ALT=C,BAND=33T)'], 'sample3':['REC(CHR=2,,POS=87532,,REF=A,ALT=C,,BAND=1243D)','REC(CHR=4,,POS=2453344432,,REF=C,,ALT=T,BAND=EE3)','REC(CHR=8,,POS=23245332,,REF=T,,ALT=A,BAND=AA4T)'], 'sample4':['REC(CHR=2,,POS=4347532,,REF=T,,ALT=G,,BAND=GM34), REC(CHR=2,,POS=4323432,,REF=A,,ALT=T,,BAND=GMA34), REC(CHR=2,,POS=44423432,,REF=G,,ALT=T,,BAND=GSSMA34)','REC(CHR=4,,POS=225332,,REF=G,,ALT=A,BAND=EER4T)','REC(CHR=8,,POS=245332,,REF=A,,ALT=C,BAND=AA4T)']} df1 = pd.DataFrame(d, index=['PP25','COX4','P53']) # 1. 确保所有列转为字符串(处理原始数据非字符串类型的情况) df1 = df1.astype(str) # 2. 把每个单元格的多个REC拆分,转为长格式(每行一个REC) # 先把DataFrame转为堆叠格式,再拆分每个单元格的REC条目 stacked_df = df1.stack().reset_index() stacked_df.columns = ['index', 'sample', 'rec_content'] # 拆分多个REC, explode成多行 stacked_df['rec_content'] = stacked_df['rec_content'].str.split(r',\s*REC\(') # 处理拆分后的第一个REC,补回REC(前缀 stacked_df['rec_content'] = stacked_df['rec_content'].apply(lambda x: ['REC(' + item if not item.startswith('REC(') else item for item in x]) stacked_df = stacked_df.explode('rec_content', ignore_index=True) # 3. 用正则表达式提取POS、REF、ALT字段 # 正则匹配POS=后面的数字,REF和ALT后面的非逗号/括号内容 pattern = r'POS=(\d+).*?REF=([^,)]+).*?ALT=([^,)]+)' extracted = stacked_df['rec_content'].str.extract(pattern) extracted.columns = ['POS', 'REF', 'ALT'] # 4. 合并结果,保留原始索引 final_df = pd.concat([stacked_df[['index']], extracted], axis=1) # 去掉可能的空值(如果有的话) final_df = final_df.dropna().reset_index(drop=True) print(final_df)
代码解释
- 转为字符串:用
astype(str)确保所有单元格都是字符串类型,解决原始数据非字符串的问题。 - 拆分并扁平化REC条目:通过
stack()把宽表转成堆叠格式,再用str.split()拆分每个单元格里的多个REC,最后explode()把每个REC变成单独一行。 - 正则提取字段:用正则表达式精准匹配
POS=后的数字,REF=和ALT=后的内容(直到遇到逗号或括号为止),确保能正确提取字段值。 - 整理结果:把原始索引和提取的字段合并,得到你需要的格式。
最终输出
| index | POS | REF | ALT | |
|---|---|---|---|---|
| 0 | PP25 | 345432 | G | A |
| 1 | PP25 | 245332 | T | GA |
| 2 | PP25 | 34545432 | T | A |
| 3 | PP25 | 87532 | A | C |
| 4 | PP25 | 4347532 | T | G |
| 5 | PP25 | 4323432 | A | T |
| 6 | PP25 | 44423432 | G | T |
| 7 | COX4 | 23332 | A | G |
| 8 | COX4 | 45332 | G | GAGG |
| 9 | COX4 | 2453344432 | C | T |
| 10 | COX4 | 225332 | G | A |
| 11 | P53 | 3335332 | G | A |
| 12 | P53 | 445332 | G | C |
| 13 | P53 | 23245332 | T | A |
| 14 | P53 | 245332 | A | C |
内容的提问来源于stack exchange,提问作者Chip
相关产品推荐
相关产品推荐

