在NFS上,Pandas read_csv超级慢

时间:2016-04-06 12:04:07

标签: python python-2.7 pandas nfs

我有一个非常简单的脚本,它使用pandas.parse_csv方法加载大型数据集。

import pandas as pd
import numpy as np

USE_COLUMNS = [0,1,2,11,13,14]

def parse_csv(filename):
    df = pd.read_csv(filename,
                     header=None,
                     compression='bz2',
                     delim_whitespace=True,
                     dtype={11:np.float32, 13:np.float32, 14:np.float32},
                     skip_blank_lines=True,
                     skiprows=4,
                     parse_dates=[[1,2]],
                     usecols=USE_COLUMNS,
                     error_bad_lines=False,
                     infer_datetime_format=True,
                     iterator=True,
                     chunksize=100000,
                     low_memory=False,
                     engine='c')
    return df

fname = 'test.log.bz2'
iter = parse_csv(fname)
df = pd.concat([chunk[chunk[14] > 60000] for chunk in iter])
print df

文件test.log.bz2压缩为1.1GB,未压缩为5 + GB,它只有15列,其中只有一些被使用。在我的本地计算机上,此脚本需要大约200秒才能运行。但在生产机器上它运行53分钟(x16减速)!我该如何解决这个问题?

在我的本地机器上,我正在使用SATA SSD,在生产机器上,NFS支持的文件系统是唯一的选择。

我正在使用pandas版本0.16.2。

我在strace下的本地机器上运行这个脚本,结果是:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 57.09    0.038753           2     15618           mremap
 18.83    0.012780           0    109476           munmap
 14.81    0.010055           0    109669           mmap
  3.44    0.002337           0    259922           read
  2.10    0.001427           0      5549      4780 open
  1.45    0.000987           1       713           brk

strace导致生产环境:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 92.41    0.491816          46     10766           mremap
  4.59    0.024412           7      3491      2814 open
  0.76    0.004065           0      9897           read
  0.75    0.003999          15       274       274 unlink
  0.50    0.002652           3       974       838 stat
  0.47    0.002498        1249         2           clone
  0.35    0.001865           0      4659           munmap
------ ----------- ----------- --------- --------- ----------------
100.00    0.532200                 37118      3997 total

1 个答案:

答案 0 :(得分:0)

我建议您在将数据加载到pandas之前预先过滤数据(使用标准工具:bzip2gawk):

bzip2 -dc /path/to/test.log.bz2 | gawk -F"," 'NR > 4 && $15 > 600000.0 {print}' > /path/to/test_filtered.log

这应该更快,并且会消耗更少的内存

请注意$15而不是chunk[14] - AWK计算从1开始的列

之后,您只需将预过滤的未压缩CSV加载到pandas

即可

PS你可能还想要tune up你的NFS