【问题标题】:Split Large csv File into multiple files depending on row value python根据行值python将大型csv文件拆分为多个文件
【发布时间】:2022-01-12 05:56:54
【问题描述】:

背景

我有一个特定格式 (NEM12) 的大型 csv 文件,它太大而无法使用。文件格式如下;

  • 文件始终以 100 开头
  • 带有 200 的行表示新数据集的开始
  • 300 或 400 的行表示数据集的数据
  • 文件总是以 900 结尾

下面的例子

100 NEM12               
200 NMI INFO    INFO        
300 20211001    0   0   0   0
400 20  20  F17     
300 20211002    0   0   0   0
300 20211003    0   0   0   0
200 NMI INFO    INFO        
300 20211001    0   0   0   0
300 20211002    0   0   0   0
300 20211003    0   0   0   0
300 20211004    0   0   0   0
300 20211005    0   0   0   0
…                   
200 NMI INFO    INFO        
300 20211001    0   0   0   0
300 20211002    0   0   0   0
400 20  20  F17     
300 20211003    0   0   0   0
300 20211004    0   0   0   0
900 

我想做的事

我正在尝试将大文件拆分为数百个小文件。每个较小的文件将包含一个 200 行以及相应的 300 和 400 行的值。

我的尝试

我尝试通过 pandas 读取文件,但由于其形状不规则,没有奏效。

我已经成功地通过下面的代码遍历了行,但是它将每个值拆分到自己的列中(即,它不是 200,而是 2、0、0)。

感谢您的帮助。

for line in open(test):
    if left(line, 3) == '200':
        try:
            with open(fname, 'a', newline='') as f_object:
                writer_object = writer(f_object)
                writer_object.writerow('900')
            f_object.close()
        except NameError:
            print('ignore')
        fname = str(line.replace(',', '').replace('\n', '')) + '.csv'
        with open(fname, 'w', newline='') as f_object:
            writer_object = writer(f_object)
            writer_object.writerow('100')
            writer_object.writerow(line)
    if left(line, 3) == '300' or left(line, 3) == '400':
        with open(fname, 'a', newline='') as f_object:
            writer_object = writer(f_object)
            writer_object.writerow(line)

【问题讨论】:

标签: python csv export


【解决方案1】:

感谢@Ferdy 的帮助,

使用您提供的代码以及我的原始代码,我能够解决问题

from csv import writer

for line in open(test):
    if line.startswith('200'):
        try:
            with open(fname, 'a', newline='') as f:
                w = writer(f)
                w.writerow(['900'])
            f.close()
        except NameError:
            print('ignore')
        flist = [str(line).split(",")[x] for x in [1, 3, 6, 7, 8]]
        fname = '_'.join(flist) + '.csv'
        print(fname)
        with open(fname, 'w', newline='') as f:
            w = writer(f)
            w.writerow(['100', 'NEM12', 'DATECREATED', 'MDYMDP', 'NAME'])
            w.writerow(str(line).split(","))
    if line.startswith(('300,', '400,')):
        with open(fname, 'a', newline='') as f:
            w = writer(f)
            w.writerow(str(line).split(","))

【讨论】:

    【解决方案2】:

    这是一种方法。

    fn = 'NEM12#000000000000001#CNRGYMDP#NEMMCO.csv'
    
    cnt = 0
    outfn = f'out_{cnt}.csv'
    
    with open(fn, 'r') as f:
        for line in f:
            if line.startswith('100,'):  # don't write
                continue
            elif line.startswith('900'):  # don't write
                continue
            elif line.startswith('200,'):  # write detect start
                cnt += 1
                outfn = f'out_{cnt}.csv'  # new filename
                
            if line.startswith(('200,', '300,', '400,')):
                with open(outfn, 'a') as w:  # write
                    w.write(f'{line}'):
    

    输出将是out_1.csv, out_2.csv etc

    【讨论】:

    • 这个,除了在处理以300400 开头的行的代码中并不明显。我会在最后的 with open( 之前添加一条注释,将任何其他行 200/300/400 附加到当前的新输出文件中。
    • 感谢提示,我修改了代码,严格写在第200、300和400行。
    猜你喜欢
    • 2022-01-16
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-23
    • 2023-03-17
    • 2012-04-14
    • 2015-09-03
    相关资源
    最近更新 更多