用Python对体积较大的CSV文件进行比较的经验

用Python对体积较大的CSV文件进行比较的经验 » 进化的测试 | 进化的测试

03 2010
 

最近的工作总是跟数据打交道,需要经常比较一些CSV文件,这些CSV文件其实都需要被LOAD到数据库里面,所以也就是一堆堆的数据文件需要比较。暂时没有发现有比较好用的现成的CSV比较工具,自己动手用Python做了一个凑合能用的。思想比较简单,就是把CSV文件的内容读取出来,保存为一个list,然后把2个CSV文件所生成的list进行对比。有个特殊的需求,就是对于CSV文件中一些肯定不一样的列,例如process date这样的字段,是需要跳过的。由于本地生成的CSV文件比较小,刚开始没有注意到如果文件太大的话会占用很多的内存。最开始的版本是:

def readcsv2list(filename, rows):
    fileobj = open(filename, 'rb')
    csvreader = csv.reader(fileobj)
    retlist = []
    for row in csvreader:
        clist = []
        selected_rows = [ic for ic in range(len(row)) if ic not in rows]
        for c in selected_rows:
            clist.append(row[c])
        retlist.append(clist)
 
    fileobj.close()
    return retlist

后来用这个脚本比较生产环境数据的时候就遇到问题了,其中最大的一个数据文件大概是1.5GB,这只是文件大小,把文件转成list以后所占用的内存会翻几倍(这个很容易理解,整数1在文件里面站1个字节,放到list里面就要4个字节了)。一下子把机器的内存用光了。随后找了一下文档,csv.reader是没有一个方法可以指定一次读取若干行数据的。后来就利用file object有一个readline()方法,通过一个参数来控制一次读取多少行的记录,从而达到控制内存使用量的目的。需要的注意的点有:1. 在读完若干行数据以后,需要获取一下当前这个file object的位置,Python提供了.tell()方法来获取这个值;2. 读取文件的时候需要知道上一会读到什么地方了,并且从那里继续往下读,用到了.seek()方法;3. readline()方法在读到文件末尾的时候只会返回一个空字符,所以需要对这个空字符做一点处理。

def readcsv2list(filename, rows, last_position, max_line):
    fileobj = open(filename, 'rb')
    fileobj.seek(last_position)
    datalines = []
    for i in range(max_line):
        line_itme = fileobj.readline()
        if len(line_itme) > 0:
            datalines.append(line_itme)
        else:
            break
 
    csvreader = csv.reader(datalines)
    retlist = []
    for row in csvreader:
        clist = []
        selected_rows = [ic for ic in range(len(row)) if ic not in rows]
        for c in selected_rows:
            clist.append(row[c])
        retlist.append(clist)
 
    current_position = fileobj.tell()
    fileobj.close()
    return retlist, current_position

Python,尤其是低版本(例如我们用的2.4.3),对于在程序里面显式地del一些变量(通常是个大list之类),是不会立刻释放内存的,所以对于处理数据量比较大的case的时候就需要特别注意内存的使用。参考文章:
Python Memory Management
Why doesn’t Python release the memory when I delete a large object?

posted on 2013-09-17 01:50  lexus 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/lexus/p/3325530.html

Python中,批量对CSV文件进行转置可以通过多种方式实现。以下是一个简单的示例,使用了Python内置的`csv`模块来读取CSV文件,并将数据转置后写入新的CSV文件中。 首先,你需要确定所有待转置的CSV文件具有相同数量的列,这样转置才是有意义的。下面是一个简单的脚本示例,它会读取指定目录下的所有CSV文件,并将它们转置后保存在同一目录下: ```python import csv import os import shutil # 设置工作目录,这里假设所有CSV文件都在这个目录下 work_dir = 'path/to/csv_files' # 设置输出目录,用于存放转置后的CSV文件 output_dir = 'path/to/output_transposed_files' # 确保输出目录存在 if not os.path.exists(output_dir): os.makedirs(output_dir) # 遍历工作目录中的所有文件 for filename in os.listdir(work_dir): if filename.endswith('.csv'): # 检查文件后缀是否为.csv input_file = os.path.join(work_dir, filename) output_file = os.path.join(output_dir, 'transposed_' + filename) # 读取原始CSV文件并转置数据 with open(input_file, 'r', newline='') as f: csv_reader = csv.reader(f) rows = list(csv_reader) columns = list(zip(*rows)) # 将转置后的数据写入新的CSV文件 with open(output_file, 'w', newline='') as f: csv_writer = csv.writer(f) csv_writer.writerows(columns) print('转置完成!') ``` 这段代码假设所有CSV文件的第一行都是列标题,并且后续行都是数据。它首先创建了一个转置后的列的列表,然后将这个列表写入到新的CSV文件中。 请根据你的具体需求进行调整,例如,你可能需要忽略原始文件的第一行,或者处理不同的文件编码等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值