【问题标题】:Pandas - why is read_csv with chunking 'on' faster than without for small files?Pandas - 为什么 read_csv 与小文件相比,分块'on' 更快?
【发布时间】:2016-06-14 09:47:45
【问题描述】:

我正在将一个包含字符串、整数和缺失值的大表 (90*85000) 读入 pandas。该文件很容易融入我的记忆。我还在具有大量内存的服务器上运行脚本,观察到相同的行为。

我认为批量读取文件会更快或与分块一样快。但是,使用 'chunksize=any_number' 时,pandas 读取文件的速度几乎快了 300 倍(11.138 秒对 0.039 秒)。

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

我的代码:

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

【问题讨论】:

    标签: python csv pandas dataframe


    【解决方案1】:

    因为在第二部分中您创建了一个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
    

    【讨论】:

    • 甚至不是我认为的第一个 :-)(因为它只是返回一个迭代器)
    • 不错的答案。为了方便熊猫新读者,我建议您可以明确指出,在第一个示例中,数据实际上已被读入数据框对象,而在第二个示例中,读取器已创建,但数据尚未从磁盘读取。
    • @JRichardSnape,这是一个很好的观点,谢谢!我已经更新了答案
    • @MaxU 感谢您的回答。我不清楚创建的迭代器对象在迭代之前不会读取文件。
    • @Dahlai,不客气! :) 感谢您接受答案!
    猜你喜欢
    • 1970-01-01
    • 2017-02-17
    • 1970-01-01
    • 2013-05-22
    • 1970-01-01
    • 2015-05-10
    • 1970-01-01
    • 2021-04-17
    • 2012-09-14
    相关资源
    最近更新 更多