这两天掌柜遇到要读取大型(基本都超过1G)的CSV文件到单个DataFrame里面的操作,搜了一下,这里结合自身实际情况做个总结,希望对有同样需求的朋友有帮助!下面直接看案例吧👇

除了一个小于1G的CSV文件,其余都大于1.3G。。。好了,现在掌柜要读取其中一个大型CSV文件到单个DataFrame中,那应该怎么操作呢?

  • 第一种:使用chunksize模块。
  • 优点:步骤简单,且对内存相当足(>=16G)的电脑适用。
  • 缺点:如果你的电脑/云/服务器内存不足以支撑这些大型文件(比如你的内存只有2G,但是文件 >= 4G的情况下),同样会出现Memory error(内存泄漏)
  • 具体方法:
import pandas as pd
import numpy as np

df_chunk = pd.read_csv('YourFileName.csv', chunksize=1000000, iterator = True) #使用chunksize分块读取大型csv文件,这里每次读取chunksize为100万

chunk_list = [] 

for chunk in df_chunk:
    chunk_list.append(chunk)

df_concat = pd.concat(chunk_list) #再把这些块组合成一个DataFrame
df_concat.shape

整合后的DataFrame大小如下:

(其实这还是掌柜选取最小一个文件读出来的数据。。。可见其他文件都是大于1000万行的😂)

  • 第二种:对读取的每列数据进行类型转换,减少内存占用。(推荐使用)

  • 优点:极大的压缩了文件内存,即便是内存不大的电脑/服务器也可以使用。

  • 缺点:初次使用的步骤相对复杂,需先提取部分数据来找出合适的转换类型。(这里如何找到每列特征对应的数据转换类型, 建议参考这个博客👉:Tutorial: Using Pandas with Large Data Sets in Python写的很详细,掌柜就不再写了。
    这里附上常见的数据类型在pandas里面

  • 具体方法:

import pandas as pd
import numpy as np


MAX_ROWS = XXX 
df = pd.read_csv('YourFileName.csv', nrows = MAX_ROWS)
df.info()

...... #比如这里可以先设置读取行数为10万条数据,然后进行分析,找到需要转换的数据类型后再全部数据查看;防止内存泄漏

df = pd.read_csv('YourFileName.csv', dtype = {
   
                              #这里就是你要转换的数据列名字和对应类型,下面随意举例
                                   'column_1': np.uint16,
                                   'column_2': np.float32,
                                   'column_3': np.float32,
                                   'column_4': np.float32,
                                   'column_5': np.uint8,
                              })
df.info()
  • 第三种:只读取可能有用的部分特征列到DataFrame中。
  • 优点:省内存,步骤简单。
  • 缺点:需要先对整个数据集提取小部分行数进行一个整体的分析,最后才能知道哪些特征是有用的。
  • 具体方法:
import pandas as pd

df = pd.read_csv('YourFileName.csv', nrows = 100000)
df.info()
......  
#此处省略各种分析方法,最后得到如下有用特征和无用特征
use_cols = ['column_1', 'column_2', 'column_3', 'column_4', 'column_5']
unused_cols = ['column_6', 'column_7']

df = pd.read_csv('YourFileName.csv', usecols=use_cols)
df.info()
  • 第四种:使用并行计算库Dask。(推荐使用)
  • 优点:能在集群中进行分布式计算,方便快捷高效。
  • 缺点:对新手来说,虽然需要花点时间去熟悉Dask的使用方法,建议参考官方文档,但不是很难。
  • 具体方法:
import dask.dataframe as dd

df = dd.read_csv('YourFileName.csv')
df.head()

下面是掌柜使用Dask读取了1.3G的CSV文件后的一个运行时间:


可以看出来Dask的计算效率是很不错的,只用了17.1ms就读取了1.3G+的CSV文件;而且掌柜这还是在内存只有2G的云服务器上面操作的,并没有发生(由Memory Error造成的)Kernel died的情况。

好了,主要的四种方法掌柜已经在这里分享了,大家按自己的需求来选取使用😁。如果你有更好的方法,欢迎在下面评论,谢谢。

参考资料:
3 simple ways to handle large data with Pandas
Tutorial: Using Pandas with Large Data Sets in Python
Dask官方文档