生信脚本计算资源使用指南

作为生物信息学从业人员,经常需要自行开发脚本进行数据格式整理和格式转换。因此,虽然PythonR中自带的包可以很轻松的实现绝大多数功能,但是其在处理大型数据(指超过1G以上的数据)时,其效率实在不敢恭维。

虽然可以通过给这些程序分配更多的内存来解决这一问题,但是在实际生产或数据荟萃分析时,无限上调内存显然是不现实的。因此需要生信脚本编写者更好的对计算资源(本文只涉及内存、CPU)加以更合理的使用。

下面将会简单介绍在PythonR中减少内存消耗上限的小技巧,供大家参考。


1. Python

目前 Python 作为数据挖掘领域最为主流的语言之一,其内设的扩展包(pandasnumpyscipy等)基本上解决了绝大多数基础操作的需要。但是过于方便的使用,就造成了这些包,在处理小数据时简洁优雅,但是处理数据量较大的数据时,就相对苦手了,尤其是pandas。下面是几个针对pandas的小建议:

1.1 Pandas 数据框瘦身方案

改变数据基本数据类型,可以对内存占用提供较大的优化空间。数据类型名称前面的数字是指存储值所需的内存位数。

例如:

  • int8使用8位或 1 字节
  • int16使用 16 位或 2 个字节。

范围越大,它消耗的内存就越多。这意味着int16使用两倍的内存,int8而int64使用八倍的内存int8。uint8等uint16 是指无符号整数,而 int指的是有符号整数。分配的内存量没有区别,但顾名思义,无符号整数只能存储正值,即 0-255,对于uint8。 这同样适用于uint16,uint32和uint64。

对于pandas.read_csv(),在默认情况下,会直接使用int64 和 float64 作为默认的整型和浮点型变量的类型,其实对于很多数据而言,这种类型指定纯属杀鸡用牛刀了,比如对于基因组坐标,int16 也就差不多够用。对于bedgff或者vcf文件来说,通过类型的转化,可以节约的内存是相当客观的。


1.2 对于读入大数据框的优化

对于生信操作而言,表格之间的相互关联也是常规操作。但是很多情况下,我们需要读一个非常大的数据集,来和小的数据集进行关联(常见于注释)。这种情况下,将整个数据库都扔进内存,显然不是最好的实现注释过程的方式。

对于这种情况,通过采用SQLite 以磁盘空间换取内存相对更小的占用,其实才是更为合理的实现方式。

import sqlite3
from sqlalchemy import create_engine
csv_database = create_engine('sqlite:///csv_database.db')

chunk_size=50000

batch_no=1

for chunk in pd.read_csv('yellow_tripdata_2016-02.csv',chunksize=chunk_size,iterator=True):
    chunk.to_sql('chunk_sql',csv_database, if_exists='append')
    batch_no+=1
    print('index: {}'.format(batch_no))

### this example is from https://towardsdatascience.com/loading-large-datasets-in-pandas-11bdddd36f7b

1.3 大数据框排序

排序问题基本上算是在算法领域最基础的问题了,但是在Python的pandas 中提供的sort 函数,给出的方案其实不是特别适合大量数据,因为其实现的基本原理是将数据全部读到内存中,然后再进行排序。当你需要把一个几十G的文件load到内存中的时候,这种就实在不是一个合理的解决方式。

除了上述利用数据库工具解决之外,也可以通过Linux shell中自带的split + sort 工具实现分步排序法。例如:

split -l 1000 data.csv data
sort -nrk3 data.csv
sort -m sorted_data_* > final_sorted_data.csv

2. R

对于R 本人没有其他特殊建议,但是很多时候R中涉及的最多的是构造一个数据结构,但是数据结构需要通过数据框或者其他类型的数据进行转化。

此时,用于构建数据对象的变量其实可以释放。R解析器不会自动的为你做上述操作,需要通过R中的rm函数进行释放。

library(Seurat)

expr_data = read.csv("data.csv")
seurat_obj = Create_10XChrome(expr_data)

##### 

rm(list = "expr_data") ### 删除过渡数据expr_data

3. 小结

上述是一些生信常用工具中节省内存的方式,其实从功能上来说,绝大多数的扩展包内的自带函数是可以解决问题的,但是性能上的优劣,主要还是看各位程序编写者的细心程度,希望大家能在自己编写脚本的过程中,合理利用计算资源。更高效的实现分析目的。 :)

Powered by XTAO TechnologyLast Modified On:2021 2023-03-24 09:05:27

results matching ""

    No results matching ""