pandas.read_csv——分块读取大文件

本文详细介绍了如何使用pandas库的read_csv函数分块读取超大csv文件,解决MemoryError问题。通过指定chunksize参数,可以有效避免内存溢出,实现数据的高效处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在读取一个超大csv文件的时候,遇到困难:

  • 首先使用office打不开
  • 然后在python中使用基本的pandas.read_csv打开文件时:MemoryError
  • 最后查阅read_csv文档发现可以分块读取。
  • read_csv中有个参数chunksize,通过指定一个chunksize分块大小来读取文件,返回的是一个可迭代的对象TextFileReader,IO Tools 举例如下:
In [138]: reader = pd.read_table('tmp.sv', sep='|', chunksize=4)

In [139]: reader
Out[139]: <pandas.io.parsers.TextFileReader at 0x120d2f290>

In [140]: for chunk in reader:
   .....:     print(chunk)
   .....: 
   Unnamed: 0         0         1         2         3
0           0  0.469112 -0.282863 -1.509059 -1.135632
1           1  1.212112 -0.173215  0.119209 -1.044236
2           2 -0.861849 -2.104569 -0.494929  1.071804
3           3  0.721555 -0.706771 -1.039575  0.271860
   Unnamed: 0         0         1         2         3
0           4 -0.424972  0.567020  0.276232 -1.087401
1           5 -0.673690  0.113648 -1.478427  0.524988
2           6  0.404705  0.577046 -1.715002 -1.039268
3           7 -0.370647 -1.157892 -1.344312  0.844885
   Unnamed: 0         0        1         2         3
0           8  1.075770 -0.10905  1.643563 -1.469388
1           9  0.357021 -0.67460 -1.776904 -0.968914
  • 指定iterator=True 也可以返回一个可迭代对象TextFileReader :
In [141]: reader = pd.read_table('tmp.sv', sep='|', iterator=True)

In [142]: reader.get_chunk(5)
Out[142]: 
   Unnamed: 0         0         1         2         3
0           0  0.469112 -0.282863 -1.509059 -1.135632
1           1  1.212112 -0.173215  0.119209 -1.044236
2           2 -0.861849 -2.104569 -0.494929  1.071804
3           3  0.721555 -0.706771 -1.039575  0.271860
4           4 -0.424972  0.567020  0.276232 -1.087401

  • 我需要打开的数据集是个csv文件,大小为3.7G,并且对于数据一无所知,所以首先打开前5行观察数据的类型,列标签等等:
chunks = pd.read_csv('train.csv',iterator = True)
chunk = chunks.get_chunk(5)
print chunk
'''
             date_time  site_name  posa_continent  user_location_country  \
0  2014-08-11 07:46:59          2               3                     66   
1  2014-08-11 08:22:12          2               3                     66   
2  2014-08-11 08:24:33          2               3                     66   
3  2014-08-09 18:05:16          2               3                     66   
4  2014-08-09 18:08:18          2               3                     66   

   user_location_region  user_location_city  orig_destination_distance  \
0                   348               48862                  2234.2641   
1                   348               48862                  2234.2641   
2                   348               48862                  2234.2641   
3                   442               35390                   913.1932   
4                   442               35390                   913.6259   

   user_id  is_mobile  is_package      ...        srch_children_cnt  \
0       12          0           1      ...                        0   
1       12          0           1      ...                        0   
2       12          0           0      ...                        0   
3       93          0           0      ...                        0   
4       93          0           0      ...                        0   

  srch_rm_cnt srch_destination_id  srch_destination_type_id  is_booking  cnt  \
0           1                8250                         1           0    3   
1           1                8250                         1           1    1   
2           1                8250                         1           0    1   
3           1               14984                         1           0    1   
4           1               14984                         1           0    1   

   hotel_continent  hotel_country  hotel_market  hotel_cluster  
0                2             50           628              1  
1                2             50           628              1  
2                2             50           628              1  
3                2             50          1457             80  
4                2             50          1457             21  

[5 rows x 24 columns]
'''
  • 最后需要合并多个chunk可以使用如下代码
df = pd.concat(df_list, ignore_index=True)
<think>我们正在处理用户的问题:如何在pandasread_csv函数中按条件筛选数据。 根据引用,我们注意到用户可能已经尝试过一些方法,比如在读取后使用条件过滤(如data[data['Id'] < 116512]),但用户希望的是在读取过程中就进行筛选。 然而,需要明确的是:read_csv函数本身并不支持在读取时按条件筛选(比如根据某列的值进行过滤),它主要用于读取整个文件并转换为DataFrame。条件筛选通常在读取完成后进行。 但是,我们可以考虑一些替代方案: 1. 读取整个文件,然后使用布尔索引进行筛选(如引用[3]所示)。 2. 如果文件非常大,我们可以考虑分块读取chunksize)并逐块筛选,这样可以减少内存占用。 3. 如果条件是基于某一列的值,并且我们只需要部分列,可以使用usecols参数先选择需要的列,然后再进行条件筛选,这样也能节省内存。 因此,回答的重点应该是: - 首先说明read_csv本身不支持条件筛选,但可以在读取后筛选。 - 提供读取后筛选的示例。 - 对于大文件,建议分块读取和筛选。 另外,用户引用的内容中提到了dtype和性能问题,但用户当前的问题是关于条件筛选的,所以我们主要关注筛选。 根据引用[3]中的示例,用户已经知道如何读取后筛选,但可能希望更高效的方法(尤其是大文件)。 因此,我们可以这样组织回答: 1. 直接使用布尔索引(适用于小文件): data = pd.read_csv('file.csv') filtered_data = data[data['column_name'] > 10] 2. 对于大文件,使用分块读取: chunks = pd.read_csv('large_file.csv', chunksize=10000) filtered_chunks = [] for chunk in chunks: filtered_chunk = chunk[chunk['column_name'] > 10] filtered_chunks.append(filtered_chunk) filtered_data = pd.concat(filtered_chunks, ignore_index=True) 3. 如果条件是基于行索引(比如行号),可以使用skiprows参数,但这不是条件筛选,而是跳过某些行。不过,如果条件可以转化为行号,也可以使用。但用户的问题是一般条件,所以不重点提。 4. 注意:在读取时无法进行条件筛选,因为read_csv是逐行读取并解析的,而条件可能涉及多行(虽然通常条件是按行的),但pandas没有提供这样的接口。 5. 另外,如果条件只涉及某些列,可以使用usecols减少读取的列,从而节省内存。 示例代码: 情况1:读取后筛选 情况2:分块读取并筛选 同时,生成相关问题。 注意:用户引用的内容中提到了dtype和性能,我们可以稍微提一下使用dtype来减少内存,但这不是用户问题的核心。 因此,回答如下:</think>### 如何在 pandas read_csv 中按条件筛选数据 在 pandas 中,`read_csv()` 函数本身**不支持直接嵌入条件筛选**,但可以通过以下两种高效方式实现按条件筛选数据: #### 方法 1:读取后立即筛选(推荐) ```python import pandas as pd # 读取整个文件 data = pd.read_csv('data.csv', encoding='gbk') # 根据文件编码调整 # 按条件筛选(示例:筛选"Age"列大于30的行) filtered_data = data[data['Age'] > 30] # 替换为你的实际列名和条件 ``` - ✅ **优点**:代码简洁直观,支持复杂条件(如多列组合条件) - ⚠️ **注意**:大文件可能消耗内存,需评估数据规模[^3] #### 方法 2:分块读取筛选(适合超大文件) ```python chunk_list = [] for chunk in pd.read_csv('large_data.csv', chunksize=10000): # 每次读取1万行 filtered_chunk = chunk[chunk['Salary'] < 5000] # 筛选条件 chunk_list.append(filtered_chunk) filtered_data = pd.concat(chunk_list) ``` - ✅ **优点**:内存友好,可处理超过内存大小的文件 - 🔧 **优化点**:结合`usecols`参数只读取必要列减少内存[^2] ```python pd.read_csv(..., usecols=['Col1', 'Col2']) # 仅读取指定列 ``` #### 性能优化建议 1. **指定数据类型**:用`dtype`参数明确列类型,加速读取 ```python pd.read_csv(..., dtype={'Age': 'int32', 'Price': 'float32'}) ``` 2. **使用C引擎**:添加`engine='c'`提升解析速度(默认启用) 3. **跳过无效行**:通过`skiprows`跳过无关数据行[^1] > ⚠️ **重要提示**:所有条件筛选操作都发生在数据加载到 DataFrame 后,因 CSV 是纯文本格式,无法在读取时直接应用条件过滤。 --- ### 相关问题 1. 如何优化 pandas 读取超大 CSV 文件的性能? 2. 读取 CSV 时如何自动处理缺失值或异常格式? 3. 除了 CSVpandas 还支持哪些数据格式的读取和筛选? 4. 如何将筛选后的数据高效导出为新文件? [^1]: Pandas read_csv 读取性能优化参数 [^2]: 数据类型 dtype 指定方法 [^3]: 基于单列数据的过滤条件实现
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值