生信log

生信log36|如何处理超大的文件:以处理VCF文件为例附pyt

2023-06-03  本文已影响0人  小周的万用胶囊

以前自学机器学习的时候经常遇到一些,10几个G甚至更大的数据集,自己的电脑的存储不太够,就没有做那些数据集了。直到最近因分析需求需要清洗100G+的数据,才真正接触到真正意义上的大数据,过程中发现脚本跑得慢已经是次要问题,因文件太大了导致内存过多,以至于处理的过程中被系统Ctrl + C,看了一圈也问了大模型,总结了下面这些注意点。PS:下面说的“超量”指处理超过内存大小的文件。

以处理VCF文件为例

1、如何“超量”读写文件内容

import csv
with open("test.vcf", "r") as f:
    record = csv.reader(f, delimiter="\t")
    for info in record:
        print(info)

# 生成
def extract_data(超大文件):
    XXX #提取的步骤
    yield data
#法一
import sys
sys.stdout.write(data)
# 法二
print(data)

2、如何“超量”地处理大数据

超量处理数据

MapReduce简介
Python实现Map Reduce
import pandas

#可以先事先定义一个处理df的函数
def clean_df(df):
    do_anything df
    return df
merge_data = pd.Dataframe()
for chunk in df:
    tmp_df = clean_df(chunk)
    merge_data = pd.concat([tmp_df, merge_data] )
linux实现MapReduce
split -n l/10 bigfile smallfile
# 分布式处理文件
# 法一
parallel -j 4 "cat {} | tr ' ' '\n' | sort | uniq -c" ::: smallfile*
# 法二
ls script.sh |xargs -I {} qsub -cwd -l vf=4g -pe smp 1 {}
# 合并文件
cat smallfile* | sort | uniq -c > result.txt

3、如何提高处理大数据的效率

使用隐式循环和列表推导式替代显式循环

a = [1,2,3]
for i in a:
  print(a+1)

#列表推导式

a = [i + 1 for i in a]

使用内置函数
尽量使用python内置函数,numpy等等因为这些函数的底层语言是C,以下提供一些常用的内置函数供大家参考。

# 获取字符串长度
string = "Hello, world!"
length = len(string)

# 获取列表长度
list = [1, 2, 3, 4, 5]
length = len(list)

# 获取元组长度
tuple = (1, 2, 3, 4, 5)
length = len(tuple)

# 获取字典长度
dictionary = {'name': 'John', 'age': 30}
length = len(dictionary)

sorted()函数:用于对列表、元组等对象进行排序。

# 对列表进行排序
list = [3, 1, 4, 2, 5]
sorted_list = sorted(list)

# 对元组进行排序
tuple = (3, 1, 4, 2, 5)
sorted_tuple = sorted(tuple)

# 对字典进行排序
dictionary = {'name': 'John', 'age': 30}
sorted_dictionary = sorted(dictionary.items())
# 获取列表中的最大值和最小值
list = [3, 1, 4, 2, 5]
max_value = max(list)
min_value = min(list)

# 获取元组中的最大值和最小值
tuple = (3, 1, 4, 2, 5)
max_value = max(tuple)
min_value = min(tuple)
# 计算列表中所有元素的和
list = [1, 2, 3, 4, 5]
sum = sum(list)

# 计算元组中所有元素的和
tuple = (1, 2, 3, 4, 5)
sum = sum(tuple)
# 过滤列表中的偶数
list = [1, 2, 3, 4, 5]
even_numbers = list(filter(lambda x: x % 2 == 0, list))

# 过滤元组中的奇数
tuple = (1, 2, 3, 4, 5)
odd_numbers = tuple(filter(lambda x: x % 2 != 0, tuple))
# 对列表中的每个元素进行平方运算
list = [1, 2, 3, 4, 5]
squared_list = list(map(lambda x: x**2, list))

# 对元组中的每个元素进行加1运算
tuple = (1, 2, 3, 4, 5)
incremented_tuple = tuple(map(lambda x: x+1, tuple))
# 对列表中的元素进行累加运算
from functools import reduce
list = [1, 2, 3, 4, 5]
sum = reduce(lambda x, y: x+y, list)

# 对元组中的元素进行累乘运算
tuple = (1, 2, 3, 4, 5)
product = reduce(lambda x, y: x*y, tuple)
# 将两个列表中的元素按照索引进行配对
list1 = [1, 2, 3, 4, 5]
list2 = ['a', 'b', 'c', 'd', 'e']
zipped_list = list(zip(list1, list2))

# 将两个元组中的元素按照索引进行配对
tuple1 = (1, 2, 3, 4, 5)
tuple2 = ('a', 'b', 'c', 'd', 'e')
zipped_tuple = list(zip(tuple1, tuple2))
# 将列表中的元素和它们的索引进行配对
list = ['a', 'b', 'c', 'd', 'e']
enumerated_list = list(enumerate(list))

# 将元组中的元素和它们的索引进行配对
tuple = ('a', 'b', 'c', 'd', 'e')
enumerated_tuple = list(enumerate(tuple))
# 判断列表中是否存在偶数
list = [1, 2, 3, 4, 5]
has_even_number = any(map(lambda x: x % 2 == 0, list))

# 判断元组中是否所有元素都是奇数
tuple = (1, 3, 5, 7, 9)
all_odd_numbers = all(map(lambda x: x % 2 != 0, tuple))

使用Cython写的第三方工具包

总结

另:感兴趣的话点个赞再走,接下来会继续梳理和分享感兴趣的点。


参考
《python》
VCF格式
cyvcf2

上一篇 下一篇

猜你喜欢

热点阅读