You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测单列值是否存在于多值格式的另一列中?

问题

当某一列包含多个值时,如何检测另一列中的值是否存在于该列中?

最小可复现示例

import pandas as pd

df1 = pd.DataFrame({'patient': ['patient1', 'patient1', 'patient1','patient2', 'patient2', 'patient3','patient3','patient4'], 
                   'gene':['TYR','TYR','TYR','TYR','TYR','TYR','TYR','TYR'],
                   'variant': ['buu', 'luu', 'stm','lol', 'bla', 'buu', 'lol','buu'],
                    'genotype': ['buu,luu,hola', 'gulu,melon', 'melon,stm','melon,buu,lol', 'bla', 'het', 'het','het']})

print(df1)

输出:

patient gene variant       genotype
0  patient1  TYR     buu   buu,luu,hola
1  patient1  TYR     luu     gulu,melon
2  patient1  TYR     stm      melon,stm
3  patient2  TYR     lol  melon,buu,lol
4  patient2  TYR     bla            bla
5  patient3  TYR     buu            het
6  patient3  TYR     lol            het
7  patient4  TYR     buu            het

已尝试方法

df1.variant.isin(df1.genotype)

结果:

0    False
1    False
2    False
3    False
4     True
5    False
6    False
7    False
Name: variant, dtype: bool

该方法无效,预期结果应为:

0    True
1    False
2    True
3    True
4    True
5    False
6    False
7    False
Name: variant, dtype: bool

注:genotype列的值数量不固定,范围在1到20之间。


解决方案

方法1:逐行检查拆分后的子项

原方法isin会把genotype的完整字符串作为匹配项,而非拆分后的单个值。我们可以直接逐行拆分genotype并检查variant是否在其中:

df1['exists'] = df1.apply(lambda row: row['variant'] in row['genotype'].split(','), axis=1)

print(df1['exists'])

输出:

0     True
1    False
2     True
3     True
4     True
5    False
6    False
7    False
Name: exists, dtype: bool

方法2:正则匹配完整子项

如果担心拆分字符串的性能问题,可以用正则确保匹配完整的逗号分隔项(避免部分匹配,比如lu匹配luu的情况):

import re

def check_variant(row):
    # 转义特殊字符,避免正则语法冲突
    pattern = re.compile(r'\b' + re.escape(row['variant']) + r'\b')
    return pattern.search(row['genotype']) is not None

df1['exists'] = df1.apply(check_variant, axis=1)

方法3:向量化拆分(适合大规模数据)

针对数据量较大的场景,逐行apply效率有限,可以先拆分genotype为多行,再通过索引匹配:

# 拆分genotype并保留原索引
geno_exploded = df1['genotype'].str.split(',', expand=True).stack().reset_index(level=1, drop=True).rename('geno_item')

# 标记原索引中存在匹配的行
df1['exists'] = df1.index.isin(geno_exploded[geno_exploded == df1['variant']].index)

原方法无效的原因

df1.variant.isin(df1.genotype)的逻辑是检查每个variant值是否完全等于genotype列中的某个完整字符串,而非是否是genotype中逗号分隔的子项。比如第0行的buu不等于buu,luu,hola,因此返回False,不符合需求。

内容的提问来源于stack exchange,提问作者Manolo Dominguez Becerra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:15:23