从CSV文件中读取随机行只读取该行并移至Python中的另一个CSV

时间:2016-10-21 08:00:37

标签: python csv random

我在从大型csv文件中读取随机行并使用Windows上的0.18.1 pandas和2.7.10 Python将其移动到另一个CSV文件时遇到问题。

我想只将随机选择的行加载到内存中,然后将它们移动到另一个CSV。我不想将第一张CSV的全部内容加载到内存中。

这是我使用的代码:

import random

file_size = 100

f = open("customers.csv",'r')

o = open("train_select.csv", 'w')

for i in range(0,50):

    offset = random.randrange(file_size)

    f.seek(offset)

    f.readline()

    random_line = f.readline()

    o.write(random_line)

当前输出如下所示:

2;flhxu-name;tum-firstname; 17520;buo-city;1966/04/24;wfyz-street;   96;GA;GEORGIA
1;jwcdf-name;fsj-firstname; 13520;oem-city;1954/02/07;amrb-street; 145;AK;ALASKA
1;jwcdf-name;fsj-firstname; 13520;oem-city;1954/02/07;amrb-street; 145;AK;ALASKA

我的问题有两个:

  1. 我想在第二个csv中看到标题,而不仅仅是行。

  2. 只能通过随机函数选择一行。

  3. 输出应该是这样的:

    id;name;firstname;zip;city;birthdate;street;housenr;stateCode;state
    2;flhxu-name;tum-firstname; 17520;buo-city;1966/04/24;wfyz-street;   96;GA;GEORGIA
    1;jwcdf-name;fsj-firstname; 13520;oem-city;1954/02/07;amrb-street; 145;AK;ALASKA
    

2 个答案:

答案 0 :(得分:1)

你做的比这更简单:

  1. 首先,完全阅读客户文件,标题是一个特例,保留它。
  2. 随机播放行列表(这就是您要查找的内容)
  3. 回写标题+洗牌行
  4. 代码:

    import random
    
    with open("customers.csv",'r') as f:
        title = f.readline()
        lines = f.readlines()
    
    random.shuffle(lines)
    
    with open("train_select.csv", 'w') as f:
        f.write(title)
        f.writelines(lines)
    
    编辑:如果您不想将整个文件保存在内存中,可以选择其他方式。唯一的缺点是你必须读取文件一次(但不能存储在内存中)来计算行偏移量:

    import random
    
    input_file = "customers.csv"
    
    line_offsets = list()
    
    # just read the title
    with open(input_file,'r') as f:
        title = f.readline()
        # store offset of the first
        while True:
            # store offset of the next line start
            line_offsets.append(f.tell())
            line = f.readline()
            if line=="":
                break
    
        # now shuffle the offsets
        random.shuffle(line_offsets)
    
        # and write the output file
        with open("train_select.csv", 'w') as fw:
            fw.write(title)
            for offset in line_offsets:
                # seek to a line start
                f.seek(offset)
                fw.write(f.readline())
    

答案 1 :(得分:0)

在OP请求中,由于我之前的2个实现必须读取输入文件,因此这是一个更复杂的实现,其中不提前读取文件。

它使用Customer Product date amount ------------------------------------------- a p1 1/31/2015 $12 a p2 1/31/2015 $13 a p2 2/28/2015 $1 来存储行的偏移对,以及最小行len(要配置),以避免随机列表太长而无需任何内容。

基本上,程序生成随机排序的偏移,范围从第二行的偏移(标题行跳过)到文件的结尾,步长为minimum_line_len。

对于每个偏移量,它检查是否尚未读取行(使用bisect,这很快但由于极端情况,进一步测试很复杂)。 - 如果没有读取,请跳回以查找上一个换行符(即读取文件,否则无法执行)将其写入输出文件,将开始/结束偏移量存储在耦合列表中 - 如果已经阅读,请跳过

代码:

bisect
  • if