如何使用正则为pandas DataFrame创建条件列并修复np.select报错
报错原因
np.select参数格式不符合要求:该函数要求传入的第一个参数是布尔序列/布尔数组组成的列表,第二个参数是和条件列表长度相等的返回值列表,你传入的是loc筛选出来的子DataFrame,第二个参数是单个字符串,二者长度完全不匹配,直接触发长度校验报错。- 原有判断逻辑存在缺陷:一是连续写9个
str.contains不仅冗余,还可能误匹配字符串其他位置出现的01-09字符;二是标签映射写反,规则要求01-09开头标记为tumor,你原有代码把non-tumor作为匹配后的标签、tumor作为默认值,结果会完全颠倒。 - 你提供的示例构造代码把样本ID设为了列名,和需求里样本ID作为行索引的结构不符,需要先转置。
修复方案
用正则精准匹配索引最后一段的开头,避免误判,单条件判断用np.where更简洁,代码如下:
import pandas as pd import numpy as np # 构造并修正示例数据结构 meth_450 = pd.DataFrame( {'TCGA-06-0125-02A':[0.1, 0.2, 0.3], 'TCGA-06-0125-12A':[0.4, 0.5, 0.6], 'TCGA-06-0125-04A':[0.7, 0.8, 0.9]} ).T meth_450.columns = ['cg001', 'cg002', 'cg003'] # 正则`-0[1-9]`精准匹配横杠后接01-09的片段,对应索引最后一段以01-09开头的规则 is_tumor = meth_450.index.str.contains(r'-0[1-9]', regex=True) meth_450['type'] = np.where(is_tumor, 'tumor', 'non-tumor')
如果要坚持使用np.select,需要严格按照参数要求传等长的条件列表和返回值列表:
meth_450['type'] = np.select( condlist=[is_tumor], choicelist=['tumor'], default='non-tumor' )
运行结果
执行后输出完全符合预期:
| cg001 | cg002 | cg003 | type | |
|---|---|---|---|---|
| TCGA-06-0125-02A | 0.1 | 0.2 | 0.3 | tumor |
| TCGA-06-0125-12A | 0.4 | 0.5 | 0.6 | non-tumor |
| TCGA-06-0125-04A | 0.7 | 0.8 | 0.9 | tumor |
内容的提问来源于stack exchange,提问作者melolilili
相关产品推荐
相关产品推荐

