如何生成更高效的代码来搜索pandas中列中的多个字符串

2024-06-14 06:20:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我是一名新自学的程序员(基本上少了一节课),在一家生物实验室工作。我有一个脚本,可以遍历来自两种不同细胞类型的RNAseq数据,并在另一个数据集中运行ttest。它为这个应用程序工作,但代码感觉非常野蛮,我知道我将编写类似的脚本很多

如何更好地编写以下代码以提高效率

项目目标:

  1. 将基因列表与两种细胞类型的rnaseq文库进行比较,如果文库中包含该基因,则对细胞类型1和细胞类型2进行测试
  2. 输出结果

:

import pandas as pd
from scipy.stats import ttest_ind
rnatest = {'Gene symbol':["GeneA","GeneB"],"rnaseq1A":[1,1.5],"rnaseq1B":[1.3,1.2],"rnaseq2A":[2.3,2.7],"rnaseq2B":[2,2.6]} 
df = pd.DataFrame(rnatest)
GOIlist = ["GeneA","GeneB"]
GOI = []
mu = [] 
pval = []
for index, row in df.iterrows():
  if row['Gene symbol'] in GOIlist:
    t, p = ttest_ind([row["rnaseq1A"],row["rnaseq1B"]],[row["rnaseq2A"],row["rnaseq2B"]])
    GOI.append(row['Gene symbol'])
    mu.append(t)
    pval.append(p)
df2 = {'Gene symbol':GOI,"tVAL":mu, "pVAL":pval}
df2 = pd.DataFrame(df2)
print(df2)  

Tags: 数据代码脚本类型symbolrow细胞pd
1条回答
网友
1楼 · 发布于 2024-06-14 06:20:31

使用pandas的优点是可以执行列操作。这些是generally more efficient then iterating over the DataFrame with a for loop

我稍微修改了你的df,向你展示了过滤掉我们需要的行的效果

>>> import pandas as pd
>>> from scipy.stats import ttest_ind
>>> GOIlist = ["GeneA","GeneB"]
>>> rnatest = {'Gene symbol':["GeneA","GeneB", "GeneC"],"rnaseq1A":[1,1.5,2],"rnaseq1B":[1.3,1.2,1.1],"rnaseq2A":[2.3,2.7,3.1],"rnaseq2B":[2,2.6,3.2]} 
>>> df = pd.DataFrame(rnatest)
>>> print(df)

    Gene symbol     rnaseq1A    rnaseq1B    rnaseq2A    rnaseq2B
0   GeneA           1.0         1.3         2.3         2.0
1   GeneB           1.5         1.2         2.7         2.6
2   GeneC           2.0         1.1         3.1         3.2

现在我将如何重写您的代码:

  1. 使用set_index使Gene symbol行成为索引,这会加快速度 加快查找时间(尤其是在数据帧较大的情况下)
  2. 使用loc筛选出具有位于GOIlist中的基因符号的行
  3. 创建两个新列pValtVal,为其分配ttest_ind的输出。请注意,我们不再需要对行进行迭代
  4. 如果不想在输出中看到rnaseq*列,可以选择删除这些列

代码:

>>> df3 = df.set_index(['Gene symbol'])
>>> df3 = df3.loc[GOIlist]
>>> df3['tVal'], df3['pVal'] = ttest_ind([df3["rnaseq1A"], df3["rnaseq1B"]], [df3["rnaseq2A"], df3["rnaseq2B"]])
>>> df3 = df3.drop(['rnaseq1A', 'rnaseq1B', 'rnaseq2A', 'rnaseq2B'], axis=1)
>>> print(df3)
            tVal        pVal
Gene symbol         
GeneA       -4.714045   0.042174
GeneB       -8.221922   0.014473

那么,这段代码现在有多高效

如果我人为地将数据帧的大小增加10.000倍(因此总共增加30.000行,而不是3行)

n = 10_000
rnatest = {'Gene symbol':["GeneA","GeneB", "GeneC"]*n, "rnaseq1A":[1,1.5,2]*n, "rnaseq1B":[1.3,1.2,1.1]*n, "rnaseq2A":[2.3,2.7,3.1]*n, "rnaseq2B":[2,2.6,3.2]*n} 
df = pd.DataFrame(rnatest)

然后我可以使用^{}来测量代码的执行时间。对于您最初的方法,我得到的结果是:

13.7 s ± 555 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

当我的方法在

45.2 ms ± 1.27 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

所以这是一个more than 300 times加速

相关问题 更多 >