2016-06-14 62 views
1

我正在读一个有点大的表(90 * 85000)的字符串,整数和缺失值到熊猫。该文件很容易进入我的记忆。我还在具有大量内存的服务器上运行脚本,观察相同的行为。熊猫 - 为什么read_csv的'on'比没有小文件快?

我会假设批量读取文件的速度会更快或与分块一样快。然而,'chunksize = any_number'大熊猫读取文件的速度提高了将近300倍(11.138s和0.039s)。

有人可以解释这种行为吗?

我的代码:

startTime = datetime.now() 
df=pd.read_csv(dataFile,delim_whitespace=True) 
print datetime.now() - startTime 

startTime = datetime.now() 
df=pd.read_csv(dataFile,delim_whitespace=True, chunksize=10) 
print datetime.now() - startTime 

回答

5

因为在第二部分,你已经创建了一个pandas.io.parsers.TextFileReader object(迭代器)...

演示:

In [17]: df = pd.DataFrame(np.random.randint(0, 10, size=(20, 3)), columns=list('abc')) 

In [18]: df.to_csv('d:/temp/test.csv') 

In [19]: reader = pd.read_csv('d:/temp/test.csv', chunksize=10, index_col=0) 

In [20]: print(reader) 
<pandas.io.parsers.TextFileReader object at 0x000000000827CB70> 

如何使用这个迭代

In [21]: for df in reader: 
    ....:  print(df) 
    ....: 
    a b c 
0 0 5 6 
1 6 0 6 
2 2 5 0 
3 3 6 2 
4 5 7 2 
5 5 2 9 
6 0 0 1 
7 4 8 3 
8 1 8 0 
9 0 8 8 
    a b c 
10 7 9 1 
11 6 7 9 
12 7 3 2 
13 6 4 4 
14 7 4 1 
15 2 6 5 
16 5 2 2 
17 9 9 7 
18 4 9 0 
19 0 1 9 

在代码的第一部分中,您已经读取了一个DF(数据框)中的整个CSV文件。显然它需要更长的时间,因为迭代器对象(上面演示中的reader)不会从CSV文件中读取数据,直到您开始迭代它为止。

示例:让我们创建一个1M行DF并比较pd.read_csv(...)pd.read_csv(..., chunksize=1000)

In [24]: df = pd.DataFrame(np.random.randint(0, 10, size=(10**6, 3)), columns=list('abc')) 

In [25]: df.shape 
Out[25]: (1000000, 3) 

In [26]: df.to_csv('d:/temp/test.csv') 

In [27]: %timeit pd.read_csv('d:/temp/test.csv', index_col=0) 
1 loop, best of 3: 1.21 s per loop 

In [28]: %timeit pd.read_csv('d:/temp/test.csv', index_col=0, chunksize=1000) 
100 loops, best of 3: 4.42 ms per loop 
+1

甚至不是第一个我觉得:-)(因为它只是返回一个迭代器) – joris

+0

@joris,是的,谢谢!我会给我的答案添加一个例子... – MaxU

+0

好的答案。为了读者对熊猫的好处,我建议你可以明确指出,在第一个例子中,数据实际上已经被读入数据框对象,而在第二个例子中,读者被创建,但数据尚未从磁盘读取。 –