Python 如何使用关键字列表将csv拆分为多个csv文件

Python 如何使用关键字列表将csv拆分为多个csv文件,python,regex,csv,Python,Regex,Csv,我试图从多台机器上读取性能报告,并希望对它们进行解析和组合,以便在单个绘图上轻松比较机器性能。一旦划分为多个csv,我计划使用pd.read_csv()读取它们,并将多个工具组合成单个df 但为了做到这一点,我必须首先处理&用分号分隔符分割相当难看的csv文件 CSV的结构如下: 关键词_01 COL_01;COL_02;COL03;。。。;上校 第1行 第2行 第3行 … 线路(m), 关键词_02 COL_01;COL_02;COL03;。。。;COL_x 第1行 第2行 第3行 … 线路y

我试图从多台机器上读取性能报告,并希望对它们进行解析和组合,以便在单个绘图上轻松比较机器性能。一旦划分为多个csv,我计划使用pd.read_csv()读取它们,并将多个工具组合成单个df

但为了做到这一点,我必须首先处理&用分号分隔符分割相当难看的csv文件
CSV的结构如下:

关键词_01
COL_01;COL_02;COL03;。。。;上校
第1行
第2行
第3行

线路(m),
关键词_02
COL_01;COL_02;COL03;。。。;COL_x
第1行
第2行
第3行

线路y
关键词_03
COL_01;COL_02;COL03;。。。;科鲁夫
第1行
第2行
第3行

线路

csv报告由多个部分组成,每个部分都以一个固定的关键字(或关键字短语)开头,每个部分都有一个固定的列数(每个部分的列数可能不同)和一个动态行数,具体取决于报告的事件数(上面的cfr结构)

  • 我创建了一个包含所有关键字的列表,称为tpm\U节

    tpm_sections = ['Summary of time consumption',
        'Equipment Indicators',
        'Batch Profile',
        'Jam Profile',
        'Jam Time Profile',
        'Jam Table',
        'Handler Model profile',
        'Miscellaneous Indicators ',
        'Tape Job Profile ']
    tpm_idx = [None]*len(tpm_sections)
    
  • 我读取我的csv并使用正则表达式将我的tpm_节列表的任何元素与我的csv文件的行相匹配,我使用函数enumerate以便我可以将行索引返回到单独的列表tpm_idx中:

  • os.listdir(输入文件夹)中文件的
    :
    input\u file=os.path.join(input\u文件夹,文件)
    如果文件.endswith('.csv'):
    tpm_date=datetime.fromtimestamp(os.path.getctime(input_file)).strftime(“%Y%m%d”)#从文件创建时间戳获取tpm报告日期
    打开(输入_文件,“r”)作为f:
    reader=csv.reader(f,分隔符=“;”)
    #对于行内读取器:
    对于i,枚举(读取器)中的行:
    如果第行为r‘机器’:
    mcpat=re.compile(r'\\\7icost\d\d')
    mcline=str(第[1]行)
    mcname=mcpat.match(mcline).group(0)[2:]
    mcid=mcname[6:]
    打印('报告日期为:'+tpm\U日期+”\n机器名称:“+mcname+”\n机器ID:'+mcid)
    对于范围内的j(透镜(tpm_截面)):
    如果第行中的tpm_节[j]:
    tpm_idx[j]=i
    打印('Section'+tpm_sections[j]+'从第行开始:'+str(tpm_idx[j]))
    tpm_dict={tpm_idx_name[i]:tpm_idx[i]表示范围内的i(len(tpm_idx))}
    
  • 我现在有一个关键字列表,一个匹配行索引列表和一个链接这两者的字典,我应该如何继续分割csv文件?我的代码,用于为将来的熊猫导入写入每个读卡器对象节的csv文件,可选]为更多结构创建每个节的子文件夹

    for j in range(len(tpm_idx_names))
    output_file = tpm_date + mcname + tpm_idx_name[j]
    with open(output_file, 'w', newline='') as o:
        if j+1 < len(tpm_idx):
            #for row_idx in range(tpm_idx[j]:tpm_idx[j+1]):
            for line in reader[tpm_idx[j]:tpm_idx[j+1]]:
                o.write(''.join())
        else:
            for line in reader[tpm_idx[j]:]:
                o.write(''.join())
    

    我认为你把问题分解成太多的小问题,使事情变得更加困难。从原始html(也是一种排序的结构化数据格式)中提取数据以及仅提取所需的数据可能是最简单的

    但是,如果您正在寻找一种方法:

    • 将现有文本文件拆分为多个文本文件
    • 在关键字行前拆分
    • 仅写入选定关键字的输出
    假设文本文件是一个分号分隔的文件,其中第一列中只有一个术语的任何行都是一个关键字行,那么这应该可以工作:

    tpm_sections = [
        'Summary of time consumption',
        'Equipment Indicators',
        'Batch Profile',
        'Jam Profile',
        'Jam Time Profile',
        'Jam Table',
        'Handler Model profile',
        'Miscellaneous Indicators ',
        'Tape Job Profile '
    ]
    out_f = None
    with open('ICOST_19_TPM_20201124.csv') as f:
        for line in f:
            parts = line.strip().split(';')
            if parts[1] and (parts[1:].count('') == len(parts) - 1):
                # new keyword line, close previous file if any
                if out_f is not None:
                    out_f.close()
                if line[1] in tpm_sections:
                    # naming the new file after the section
                    out_f = open(f'{line[1]}.csv', 'w')
                else:
                    out_f = None
            # for any line, if an output file is open at this point, write to it
            if out_f is not None:
                out_f.write(line)
        else:
            if out_f is not None:
                out_f.close()
    
    如果您不想将第一列中只有一个值的每一行识别为关键字行,而只想将具有已识别关键字的行导致拆分(并将其后面的所有内容包含在该文件中),您可以简单地更改以下内容:

            if parts[1] and (parts[1:].count('') == len(parts) - 1):
                # new keyword line, close previous file if any
                if out_f is not None:
                    out_f.close()
                if line[1] in tpm_sections:
                    # naming the new file after the section
                    out_f = open(f'{line[1]}.csv', 'w')
                else:
                    out_f = None
    
    致:


    但是,从问题或数据来看,这并不完全清楚应该是什么。这两种方法都可以。请发布一个具有预期输出的可测试样本数据,而不是像这样的
    您好,谢谢您的建议,我对在这个论坛上发帖和一般的编码都比较陌生,所以我并不总是知道最好的方法是什么。尽管如此,我还是希望保持主题的通用性,以便其他人能够从中受益。csv文件的结构非常难看,我尝试将其精简为一个简单的示例,但即使这样也会占用大量空间。。。如果我附加一个链接可以吗?附加一个链接可以,但提供一个说明问题的数据样本仍然是一个好主意-这样,人们就不会浪费时间回答一个在示例不再可用时变得不那么有意义的问题(不管你是否打算保持可用)还不清楚您对source.csv的哪个部分感兴趣?您在问题中的描述表明格式相当规则,但数据中有许多行可能需要忽略,并且各个部分的格式似乎不完全相同。您已经通过关键字说出了您想要的部分,但是您需要这些部分中的哪些部分才能最终进入输出?@Grismar感谢您的澄清。是的,格式很难看,我还附加了html版本,可以帮助可视化,但报告中的部分主要由第1点中我的tpm_部分列表中的关键字分隔。在节名称之后是一行表列,然后是可变数量的数据行。报告的每个部分都有自己的一组列,这使情况变得更糟。如果我们缩小:我想将csv分成多个关键字分隔的部分,一个部分的结尾是另一个部分的开始。我待会再收拾!谢谢谢谢,是的,的确,我认为我把这个问题弄得比本来应该更复杂。这非常有帮助,谢谢,我将反馈这两种方法中我最终使用的方法!
            if (parts[1] and (parts[1:].count('') == len(parts) - 1) and 
                (line[1] in tpm_sections)):
                # new keyword line, close previous file if any
                if out_f is not None:
                    out_f.close()
                out_f = open(f'{line[1]}.csv', 'w')