7

首先,对不起,如果这有点冗长,但我想充分描述我遇到的问题以及我已经尝试过的问题。

我正在尝试在多个条件下将两个数据框对象连接(合并)在一起。如果要满足的条件都是“等于”运算符,我知道该怎么做,但是,我需要使用 LESS THAN 和 MORE THAN。

数据框代表遗传信息:一个是基因组中的突变列表(称为 SNP),另一个提供有关人类基因组上基因位置的信息。对这些执行 df.head() 将返回以下内容:

SNP 数据帧 (snp_df):

   chromosome        SNP      BP
0           1  rs3094315  752566
1           1  rs3131972  752721
2           1  rs2073814  753474
3           1  rs3115859  754503
4           1  rs3131956  758144

这显示了 SNP 参考 ID 及其位置。“BP”代表“碱基对”位置。

基因数据框(gene_df):

   chromosome  chr_start  chr_stop        feature_id
0           1      10954     11507  GeneID:100506145
1           1      12190     13639  GeneID:100652771
2           1      14362     29370     GeneID:653635
3           1      30366     30503  GeneID:100302278
4           1      34611     36081     GeneID:645520

这个数据框显示了所有感兴趣的基因的位置。

我想找出的是所有落在基因组基因区域内的 SNP,并丢弃那些在这些区域之外的 SNP。

如果我想基于多个(等于)条件将两个数据框合并在一起,我会执行以下操作:

merged_df = pd.merge(snp_df, gene_df, on=['chromosome', 'other_columns'])

但是,在这种情况下 - 我需要找到染色体值与 Gene 数据框中的值匹配的 SNP,并且 BP 值介于“chr_start”和“chr_stop”之间。使这个具有挑战性的是这些数据帧非常大。在这个当前数据集中,snp_df 有 6795021 行,gene_df 有 34362。

我试图通过分别查看染色体或基因来解决这个问题。由于不使用性染色体,因此有 22 个不同的染色体值(整数 1-22)。这两种方法都需要很长时间。一种使用该pandasql模块,而另一种方法是循环通过单独的基因。

SQL 方法

import pandas as pd
import pandasql as psql

pysqldf = lambda q: psql.sqldf(q, globals())

q           = """
SELECT s.SNP, g.feature_id
FROM this_snp s INNER JOIN this_genes g
WHERE s.BP >= g.chr_start
AND s.BP <= g.chr_stop;
"""

all_dfs = []

for chromosome in snp_df['chromosome'].unique():
    this_snp    = snp_df.loc[snp_df['chromosome'] == chromosome]
    this_genes  = gene_df.loc[gene_df['chromosome'] == chromosome]
    genic_snps  = pysqldf(q)
    all_dfs.append(genic_snps)

all_genic_snps  = pd.concat(all_dfs)

基因迭代法

all_dfs = []
for line in gene_df.iterrows():
    info    = line[1] # Getting the Series object
    this_snp = snp_df.loc[(snp_df['chromosome'] == info['chromosome']) &
            (snp_df['BP'] >= info['chr_start']) & (snp_df['BP'] <= info['chr_stop'])]
    if this_snp.shape[0] != 0:
        this_snp = this_snp[['SNP']]
        this_snp.insert(len(this_snp.columns), 'feature_id', info['feature_id'])
        all_dfs.append(this_snp)


all_genic_snps = pd.concat(all_dfs)

任何人都可以就更有效的方法提出任何建议吗?

4

2 回答 2

2

我刚刚想到了一种方法来解决这个问题 - 通过结合我的两种方法:

首先,关注单个染色体,然后遍历这些较小数据框中的基因。这也不必使用任何 SQL 查询。我还包括一个部分,以立即识别没有任何 SNP 在其范围内的任何冗余基因。这利用了我通常会尽量避免的双 for 循环 - 但在这种情况下它工作得很好。

all_dfs = []

for chromosome in snp_df['chromosome'].unique():
    this_chr_snp    = snp_df.loc[snp_df['chromosome'] == chromosome]
    this_genes      = gene_df.loc[gene_df['chromosome'] == chromosome]

    # Getting rid of redundant genes
    min_bp      = this_chr_snp['BP'].min()
    max_bp      = this_chr_snp['BP'].max()
    this_genes  = this_genes.loc[~(this_genes['chr_start'] >= max_bp) &
            ~(this_genes['chr_stop'] <= min_bp)]

    for line in this_genes.iterrows():
        info     = line[1]
        this_snp = this_chr_snp.loc[(this_chr_snp['BP'] >= info['chr_start']) &
                (this_chr_snp['BP'] <= info['chr_stop'])]
        if this_snp.shape[0] != 0:
            this_snp    = this_snp[['SNP']]
            this_snp.insert(1, 'feature_id', info['feature_id'])
            all_dfs.append(this_snp)

all_genic_snps  = pd.concat(all_dfs)

虽然这并没有运行得非常快 - 它确实运行了,所以我实际上可以得到一些答案。我仍然想知道是否有人有任何技巧可以让它更有效地运行。

于 2015-07-15T00:14:30.690 回答
1

您可以使用以下内容来完成您正在寻找的内容:

merged_df=snp_df.merge(gene_df,on=['chromosome'],how='inner')
merged_df=merged_df[(merged_df.BP>=merged_df.chr_start) & (merged_df.BP<=merged_df.chr_stop)][['SNP','feature_id']]

注意:您的示例数据框不符合您的加入条件。这是使用修改后的数据框的示例:

snp_df
Out[193]: 
   chromosome        SNP      BP
0           1  rs3094315  752566
1           1  rs3131972   30400
2           1  rs2073814  753474
3           1  rs3115859  754503
4           1  rs3131956  758144

gene_df
Out[194]: 
   chromosome  chr_start  chr_stop        feature_id
0           1      10954     11507  GeneID:100506145
1           1      12190     13639  GeneID:100652771
2           1      14362     29370     GeneID:653635
3           1      30366     30503  GeneID:100302278
4           1      34611     36081     GeneID:645520

merged_df
Out[195]: 
         SNP        feature_id
8  rs3131972  GeneID:100302278
于 2015-07-14T15:39:59.197 回答