上节初略小结一下处理大型文件的常规思路python性能(2):multiprocessing多个参数怎么用。Python借助Pandas处理表格文件很方便,但是涉及一下大的文件,比如需要处理单个70G(笔记本内存一般16G)的csv或者txt文件,显然不能够整个将其读取运存进行分析和运算,目前我的一般思路是读取时分块,运算时并行,写出时压缩。下一节:python性能(4):pandas和geopandas读写大文件加速
pandas分块读取
以大型csv为例,可以先预览一下文件表头,使用quicklook或者读取前若干行。
1 2 3 4 5 6 7 8 9
| >>> import pandas as pd >>> geotweets = 'F:/weibo2017/geo_weibo_2017.csv' >>> df = pd.read_csv(geotweets, header=0, encoding = 'utf-8', nrows=100) >>> df.columns Index(['_id', 'Comment', 'Like', 'Transfer', 'Content', 'Co_oridinate1', 'Co_oridinate2', 'PubTime', 'Tools', 'ID', 'PicNumber', 'PicLink', 'PicAllLink'], dtype='object') >>> df.info()
|
可以分块读取并保存到本地,当然也可以逐部分进行操作最后再保存。大文件为避免有行错误添加on_bad_lines=’skip’(这里的分块chunks实际上应该是生成器)
1 2 3 4 5 6 7 8 9 10 11 12
| chunksize=3000000 set_cols = ['_id', 'Comment', 'Like', 'Transfer', 'Content', 'Co_oridinate1', 'Co_oridinate2', 'PubTime', 'ID'] chunks = pd.read_csv(geotweets,header=0,chunksize=chunksize,low_memory=False, usecols=set_cols, on_bad_lines='skip', encoding = 'utf-8') path_res_split = 'F:/weibo2017/Dataset/s1_split_chunks' i = 0 for chunk in chunks: outFileName = '{0}_{1}{2}'.format('chunk', i, '.csv') path_outfile = os.path.join(path_res_split, outFileName) chunk.to_csv(path_outfile, index=False) i = i+1
|
这里的写出可能会很慢,建议替换成二进制读写
写出二进制/压缩
尤其是对于中间计算过程的文件或者是仅用作备份的文件,可以写出压缩的二进制文件如Parquet、Feature、ORC等大数据列存储格式,或者pkl、,空间更小且读写更快,具体在后续补充性能比较
有个bug是这里最好得记录下环境中pandas的版本,不同的版本保存的文件读写不一定能兼容。python性能(4):pandas和geopandas读写大文件加速
1 2 3 4 5 6 7 8 9 10 11
|
chunk.to_feather(outdir+"test.feather") df = pd.read_feather(outdir+"test.feather")
chunk.to_parquet(outdir+"test.parquet",index=False) df = pd.read_parquet(outdir+"test.parquet")
chunk.to_pickle(outpklfile,compression={'method': 'gzip', 'compresslevel': 1, 'mtime': 1}) df = pd.read_pickle(outpklfile,compression={'method': 'gzip', 'compresslevel': 1, 'mtime': 1})
|
运算加速
高效处理的一些模块和函数+Python中的多进程并行
一方面内存足够的情况下,可以简单可以采用multiprocessing多进程,或者使用Dask dataframe,后续补充使用案例,Dask dataframe Doc
同时在操作运算的时候可以多考虑:
- 优先使用使用内置模块及内置函数
- 数据类型多使用numpy数组、内置的array,以及字典和元组
- 列表和元组、字典可以多使用列表推导式
- pandas优先使用apply函数等批量运算,避免直接逐行遍历