【问题标题】:How to speed up this Pandas for loop如何加速这个 Pandas for 循环
【发布时间】:2021-12-08 20:56:13
【问题描述】:

我在 Python 中有以下数据:

list1=[[ENS_ID1,ENS_ID2,ENS_ID3], [ENS_ID10,ENS_ID24,ENS_ID30] , ....] 

映射(一个数据框,在第一列中我有一个 Ensemble 基因 ID,在第二列中是相应的 MGI 基因 ID)

ENS_ID MGI_ID
ENS_ID1 MGI_ID1
ENS_ID2 MGI_ID2

我正在尝试获取另一个列表列表,而不是 ENS_ID 我有 MGI_ID。 为了映射 ID,我使用了一个嵌套在另一个循环中的 for 循环,但显然,作为一种方法,它确实很慢。 我怎样才能加快速度? 代码如下:

for l in ens_lists:
  mgi = []
  for i in l:
      mgi.append(mapping['MGI_ID'][mapping[mapping['ENSEMBL_ID']==i].index].values[0])
  mgi_lists.append(mgi)

【问题讨论】:

  • 不知道它是否更快,但你能对它们进行排序和压缩吗?
  • python 中的循环非常慢。您可以查看 multithreading 以提高性能。
  • 我在想是否有不带循环的不同方法
  • 您能否详细说明mapping 的结构?我虽然ENS_IDMGI_ID 是简单的常量,但mapping['MGI_ID'][mapping[mapping['ENSEMBL_ID']==i].index].values[0] 行让我觉得结构比简单的字典更复杂...
  • @surftijmen 由于 GIL,多线程对纯 Python 代码没有帮助。

标签: python pandas performance for-loop


【解决方案1】:

最好的解决方案是创建一个只有查找值的快速数据结构, 我的意思是一个键/值,一个字典可以非常快。 之后,您必须处理输入并创建查找版本。

import pandas as pd

list1=[['ENS_ID1','ENS_ID2','ENS_ID3'], ['ENS_ID10','ENS_ID3','ENS_ID2'] ] 

mapping = pd.DataFrame({'ENS_ID':['ENS_ID1','ENS_ID2','ENS_ID3','ENS_ID10'], 'MGI_ID':['MGI_ID1','MGI_ID2','MGI_ID2','MGI_ID10']})
    
lookup = dict(mapping[['ENS_ID','MGI_ID']].values)

# This is superfast
mapped_list = []
for l in list1:
    mapped_list.append([lookup[v] for v in l])

print(mapped_list)
# [['MGI_ID1', 'MGI_ID2', 'MGI_ID2'], ['MGI_ID10', 'MGI_ID2', 'MGI_ID2']]

ps:请用工作代码更正问题。

【讨论】:

    【解决方案2】:

    作为一种快速解决方案,您可以尝试使用 listcomp 而不是 append,这应该会更快:

    mgi_lists = [[mapping['MGI_ID'][mapping[mapping['ENSEMBL_ID']==i].index].values[0] for i in l] for l in ens_lists]

    为什么 listcomp 更快的一些解释是here

    【讨论】:

    • 这可能不会明显更快。
    • 感谢您的第一个解决方案,但不幸的是,正如 AKX 所说,差异并不明显
    • 您可以做的另一个小优化是将mapping['MGI_ID'] 从循环中提取出来,因为它似乎不会随着循环而改变,因此您无需支付每次迭代的字典查找成本,但同样的加速可能会非常小。
    猜你喜欢
    • 2011-09-22
    • 1970-01-01
    • 2011-05-14
    • 2020-07-15
    • 2022-01-21
    • 1970-01-01
    • 2018-03-16
    • 2021-09-03
    • 1970-01-01
    相关资源
    最近更新 更多