欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

在没有spark集群的条件下,pandas处理上亿行数据的过程探索

时间:2023-04-19

        nlp萌新,最近在尝试一个AIDD的项目,期间遇到了一个有趣的问题,当把从zinc,enamine,ChemBL,CDDI等库中收集到的数据合并到一起后,是一个60多G的txt文件,是的,您没看错,60多G的txt,几亿行。果真如文献上所说,可探索的化学空间可达到10^80……

这种东西,最好的处理方式应该是分布式,用spark集群来处理,pyspark里就有很多pandas指令。碍于手头没有可用的资源,只能用最原始的方法,尝试最大程度的简化时间。

首先在数据读入上,就出现了问题,开始的操作很生猛,六十几G的数据,直接读,结果……

 等了很久很久以后,它崩溃了

真是难为pandas了,都是我不好…… 

        接下来,只好走上了类似分期还贷的方法,把数据切成了500M每个的小文件,然后逐个处理。

        切割数据命令行如下:

# 豪横吧,五千万行一个文件(ps:这要是钱该多好啊) split -l 50000000 *.txt

        就是这样,一个大文件切割成了几十个小文件。

        我的文件只含一个smiles编码,接下来,需要RDKit及Moses包来解析,以获得weight,logP,SA,QED等其他的分子信息。

import osimport pandas as pd#显示所有列(参数设置为None代表显示所有行,也可以自行设置数字)pd.set_option('display.max_columns',None)#显示所有行pd.set_option('display.max_rows',None)#设置数据的显示长度,默认为50pd.set_option('max_colwidth',200)#禁止自动换行(设置为Flase不自动换行,True反之)pd.set_option('expand_frame_repr', False)from rdkit import rdbase, Chemfrom rdkit.Chem import PandasTools, Descriptors, rdMolDescriptors, MolFromSmilesfrom moses.metrics import QED, SA, logP, weight,mol_passes_filtersimport time# 解析smiles参数inputdir = r'./data/dataset'data = pd.Dataframe(columns = ['smiles','weight','logP','mol_passes_filters','get_n_rings' ,'SA','QED'])data_all = pd.Dataframe(columns = ['smiles','weight','logP','mol_passes_filters','get_n_rings' ,'SA','QED'])for parents,dirnames,filenames in os.walk(inputdir): for filename in filenames: df = pd.read_csv(os.path.join(parents,filename)) df.columns = ['smiles'] start = time.time() data['weight'] = df['smiles'].apply(lambda x: weight(Chem.MolFromSmiles(x))) data['logP'] = df['smiles'].apply(lambda x: logP(Chem.MolFromSmiles(x))) data['SA'] = df['smiles'].apply(lambda x: SA(Chem.MolFromSmiles(x))) data['QED'] = df['smiles'].apply(lambda x:QED(Chem.MolFromSmiles(x))) data['mol_passes_filters'] = df['smiles'].apply(lambda x:mol_passes_filters(x)) end = time.time() print(end-start) zinc_all = zinc_all.append(data,ignore_index=True)data_all.to_csv('data_all.csv')9388.2643690109258503.865498304367………………………………………………………………

平均解析一个文件9000s左右,等它解析完,柯南小学都毕业了…………

并行

上傻瓜式多线程函数——pandarallel,先来两个小简介:

最简单 pandas 多进程 方法 pandarallel - 知乎虽然 Python 有自己专门实现多进程多线程的包,可是用于 pandas 中却不是很好用,其实 pandas 有自己实现多进程的包,超级好用。 一、初次见面pandarallel 包 GitHub - nalepae/pandarallel at v1.5.2二、安装方…https://zhuanlan.zhihu.com/p/416002028GitHub - nalepae/pandarallel: A simple and efficient tool to parallelize Pandas operations on all available CPUshttps://github.com/nalepae/pandarallel先开个四线程耍耍,代码非常简单,上代码:

import osimport pandas as pd#显示所有列(参数设置为None代表显示所有行,也可以自行设置数字)pd.set_option('display.max_columns',None)#显示所有行pd.set_option('display.max_rows',None)#设置数据的显示长度,默认为50pd.set_option('max_colwidth',200)#禁止自动换行(设置为Flase不自动换行,True反之)pd.set_option('expand_frame_repr', False)from rdkit import rdbase, Chemfrom rdkit.Chem import PandasTools, Descriptors, rdMolDescriptors, MolFromSmilesfrom moses.metrics import QED, SA, logP, weight,mol_passes_filtersfrom pandarallel import pandarallelpandarallel.initialize(nb_workers=4)import timeinputdir = r'./data/dataset'data = pd.Dataframe(columns = ['smiles','weight','logP','mol_passes_filters','get_n_rings' ,'SA','QED'])dataset = pd.Dataframe(columns = ['smiles','weight','logP','mol_passes_filters','get_n_rings' ,'SA','QED'])for parents,dirnames,filenames in os.walk(inputdir): for filename in filenames: df = pd.read_csv(os.path.join(parents,filename)) df.columns = ['smiles'] start = time.time() data['weight'] = df['smiles'].parallel_apply(lambda x: weight(Chem.MolFromSmiles(x))) data['logP'] = df['smiles'].parallel_apply(lambda x: logP(Chem.MolFromSmiles(x))) data['SA'] = df['smiles'].parallel_apply(lambda x: SA(Chem.MolFromSmiles(x))) data['QED'] = df['smiles'].parallel_apply(lambda x:QED(Chem.MolFromSmiles(x))) data['mol_passes_filters'] = df['smiles'].parallel_apply(lambda x:mol_passes_filters(x)) end = time.time() print(end-start) dataset = dataset.append(data,ignore_index=True)2621.7469606399536……………………………………………………………………………………

时间节约了四分之一,我要去开十线程,二十线程去了,回见

ps:关于多线程的使用,开太少达不到最佳优化,开太多也有可能过优化,上两个博客

干货 | Python后台开发的高并发场景优化解决方案_Python大本营的博客-CSDN博客嘉宾 | 黄思涵来源 | AI科技大本营在线公开课互联网发展到今天,规模变得越来越大,也对所有的后端服务提出了更高的要求。在平时的工作中,我们或多或少都遇到过服务器压力过...https://blog.csdn.net/weixin_42232219/article/details/95131433?spm=1001.2101.3001.6650.11&utm_medium=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~Rate-11.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2~default~BlogCommendFromBaidu~Rate-11.pc_relevant_default&utm_relevant_index=16飞哥讲代码9:提升性能,线程数合适就行 - 蘭陵N梓記蘭陵N梓記 | 博客 | 软件 | 架构 | Java | Golanghttp://lanlingzi.cn/post/technical/2020/0718_code/

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。