【发布时间】:2021-03-12 23:57:36
【问题描述】:
我正在尝试从多台机器上读取性能报告,并希望解析它们并将它们组合起来,以便轻松比较单个地块上的机器性能。一旦分成多个 csv,我计划使用 pd.read_csv() 读取它们并将多个工具组合成单个 df。
但为了做到这一点,我必须首先处理并拆分带有分号分隔符的相当丑陋的 csv 文件。
CSV的结构是这样的:
KEYWORD_01;;;...;;
COL_01;COL_02;COL03;...;COL_n;
第 1 行;
Line_2;
第 3 行;
...
Line_m;
KEYWORD_02;;;...;;
COL_01;COL_02;COL03;...;COL_x;
第 1 行;
Line_2;
第 3 行;
...
Line_y;
KEYWORD_03;;;...;;
COL_01;COL_02;COL03;...;COL_f;
第 1 行;
Line_2;
第 3 行;
...
线_g;
csv 报告由多个部分组成,每个部分都以一个固定的关键字(或关键词)开头,每个部分都有固定的列数(可能因部分而异)和动态的行数,具体取决于报告的事件(上面的 CFR 结构)。
-
我创建了一个包含所有关键字的列表,称为 tpm_sections
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_sections 列表中的任何元素与我的 csv 文件的行匹配,并且我使用函数 enumerate 以便我可以将行索引返回到单独的列表 tpm_idx 中:
for file in os.listdir(input_folder):
input_file=os.path.join(input_folder, file)
if file.endswith('.csv'):
tpm_date=datetime.fromtimestamp(os.path.getctime(input_file)).strftime('%Y%m%d') # get TPM report date from file creation timestamp
with open(input_file, "r") as f:
reader = csv.reader(f, delimiter=";")
#for line in reader:
for i, row in enumerate(reader):
if r'Machine' in row:
mcpat = re.compile(r'\\\\7icost\d\d')
mcline = str(row[1])
mcname = mcpat.match(mcline).group(0)[2:]
mcid = mcname[6:]
print('Report date is: ' + tpm_date + "\nMachine Name: " + mcname + '\nMachine ID: ' + mcid)
for j in range(len(tpm_sections)):
if tpm_sections[j] in row:
tpm_idx[j] = i
print('Section '+tpm_sections[j]+' starts at line: ' + str(tpm_idx[j]) )
tpm_dict = {tpm_idx_names[i]: tpm_idx[i] for i in range(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()) -
有没有更简单的方法通过将关键字列表传递给 split() 函数来做到这一点?那太棒了,但我找不到任何可能的例子。或者通过更好地使用正则表达式,然后使用while“行不为空”循环?请记住,我的 csv 中的空行是由 ;;;;;
-
我应该改为使用 ls.append() 还是 numpy 数组创建列表列表 (LoL)?对于匹配的 tpm_section[j] 关键字之间的每一行?然后我可以轻松地为我的机器名称和 ID 添加列。我可以选择创建一个附加所有 20 台机器的 LoL/数组,或者为每台机器创建一个,然后在 pandas 中或在编写我的 csv 之前附加它们。在第 2 部分中添加的代码示例:
elif tpm_sections[j] in row: TPM_LoL.j.append(row)
【问题讨论】:
-
请发布具有预期输出的可测试样本数据,而不是这样
... -
您好,感谢您的建议,我在这个论坛上发帖和一般的编码方面都很陌生,所以我并不总是知道最好的方法是什么。话虽这么说,我想保持主题的通用性,以便其他人可以从中受益,csv 文件的结构非常丑陋,我试图将其精简为一个简单的示例,但即使这样也占用了大量空间。 . 可以附上链接吗?
-
附上一个链接是可以的,但提供一个说明问题的数据样本仍然是一个好主意 - 这样,人们就不会浪费时间回答一个意义不大的问题如果示例不再可用(无论您打算保持它可用)
-
不清楚您对源 .csv 的哪一部分感兴趣?您在问题中的描述表明格式相当规则,但数据中有许多行可能需要忽略,并且各个部分的格式似乎并不相同。您已经通过关键字说出了您想要哪些部分,但是您需要这些部分的哪些部分最终出现在输出中?
-
@Grismar 感谢您的清理工作。是的,格式很丑,我还附上了可以帮助可视化的 html 版本,但主要是报告中的部分由第 1 点中我的 tpm_sections 列表中的关键字分隔。在部分名称之后,与表格列和然后是可变数量的数据行。报告的每个部分都有自己的一组列,这使情况变得更糟。如果我们缩小:我想将 csv 分成由多个关键字分隔的部分,一个部分的结尾是另一个部分的开始。以后我会清理的!谢谢!