Python如何根据从列字符串中提取的子集数值对DataFrame行排序
Pandas DataFrame按染色体编号排序实现方案
核心逻辑
先从第一列的坐标字符串中提取染色体编号,再基于自定义优先级对编号排序,最终重排DataFrame行顺序。
实现步骤
- 提取染色体编号
利用正则匹配提取chr后到第一个冒号前的内容,刚好符合你提到的「起始索引3、结束于冒号位置」的要求:
# 提取染色体编号存入临时列chrom df['chrom'] = df.iloc[:, 0].str.extract(r'^chr(.+?):', expand=False)
- 生成排序优先级键
避免直接按字符串排序出现chr10排在chr2前的问题,自定义排序规则:
def chrom_sort_key(chrom): # 数字染色体按数值排序 if chrom.isdigit(): return int(chrom) # 性染色体自定义优先级,可根据需求调整 elif chrom == 'X': return 23 elif chrom == 'Y': return 24 elif chrom == 'MT': return 25 # 其他罕见染色体统一后置 else: return 99 # 生成排序键列 df['sort_key'] = df['chrom'].apply(chrom_sort_key)
- 重排DataFrame
按排序键升序排列后删除临时列即可:
df_sorted = df.sort_values('sort_key', ascending=True)\ .drop(columns=['chrom', 'sort_key'])\ .reset_index(drop=True)
简化版本
如果不需要自定义性染色体优先级,可直接简化为单句实现:
sort_idx = df.iloc[:, 0].str.extract(r'^chr(.+?):', expand=False)\ .apply(lambda x: int(x) if x.isdigit() else x)\ .sort_values().index df_sorted = df.loc[sort_idx].reset_index(drop=True)
效果验证
以你给出的示例数据测试:
输入行顺序:chr5:10..100、chr14:2..300、chrX:1..10
输出排序后顺序:chr5:10..100、chr14:2..300、chrX:1..10,若加入chr2、chr10的测试数据,会自动按2→5→10→14→X的顺序排列。
内容的提问来源于stack exchange,提问作者Elisa
相关产品推荐
相关产品推荐

