我有一个 SAP 生成的文件,其中包含许多列和一些不需要的行。我应该如何直接读入 Pandas?
Posted
技术标签:
【中文标题】我有一个 SAP 生成的文件,其中包含许多列和一些不需要的行。我应该如何直接读入 Pandas?【英文标题】:I have a SAP generated file with many columns and some unwanted rows. How should I read directly into Pandas? 【发布时间】:2016-01-04 12:02:20 【问题描述】:我的桌子:
Table To Be Searched MSEG
Number of hits 273208
Maximum No. of Entri 0
Runtime 00:24:17
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|Mat. Doc. |MatYr|MvT|Material |Plnt|SLoc|Batch |Customer| Amount in LC| Amount| Quantity|BUn| Qty in UnE|EUn|PO |MatYr|Mat. Doc. |Order |Profit Ctr|SLED/BBD |Pstng Date|Entry Date|Time |User name |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|4912693062|2015 |551|100062 |HDC2|0001|5G30MC1A11| | 9.03 | 9.06 | 0.083 |CS | 2 |EA | | | | |IN1165B085|26.01.2016|01.08.2015|01.08.2015|01:13:16|O33462 |
|4912693063|2015 |501|166 |HDC2|0004| | | 0.00 | 0.00 | 2 |EA | 2 |EA | | | | |IN1165B085| |01.08.2015|01.08.2015|01:13:17|O33462 |
|4912693320|2015 |551|101343 |HDC2|0001|5G28MC1A11| | 53.73 | 53.72 | 0.500 |CS | 12 |EA | | | | |IN1165B085|25.01.2016|01.08.2015|01.08.2015|01:16:30|O33462 |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Table To Be Searched MSEG
Number of hits 273208
Maximum No. of Entri 0
Runtime 00:24:17
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|Mat. Doc. |MatYr|MvT|Material |Plnt|SLoc|Batch |Customer| Amount in LC| Amount| Quantity|BUn| Qty in UnE|EUn|PO |MatYr|Mat. Doc. |Order |Profit Ctr|SLED/BBD |Pstng Date|Entry Date|Time |User name |
|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|4912696602|2015 |344|100399 |HMH3|0001|5G29MH3S11| | 0.00 | 0.00 | 9,061 |CS | 9,061 |CS | | | | |IN1165B074|26.01.2016|01.08.2015|01.08.2015|01:54:15|A70475 |
它包含超过 100 万行。以前,我首先使用以下 Python 代码将此文件转换为 CSV:
def hasNumbers(inputString):
return any(char.isdigit() for char in inputString)
with open("Input.txt") as infile:
for line in infile:
with open("Out.csv", "a") as myfile:
if line[:1] == '|':
if hasNumbers(line) == True:
newline = line[1:-2].replace(' ','')
newline.translate(None, ",!.;")
myfile.write(newline+'\n')
有没有更好的方法将这种文件转换为 CSV 格式,或者我应该如何直接将其解析为 pandas?
【问题讨论】:
抱歉,您的示例数据格式与您发布的一样吗?即多个表使用----
和|
来分隔列和行?
是的,我的示例数据与原始数据相同,但它们之间有很多行
***.com/a/58269521/11262633中的答案不需要打开文本文件两次。
【参考方案1】:
您可以使用itertools.ifilter
仅过滤表数据并使用csv.reader
来解析重要行,如下所示:
import csv
import itertools
import StringIO
with open('input.txt', 'rb') as f_input:
for line in itertools.ifilter(lambda x: len(x) > 2 and x[0] == '|' and x[1].isalpha(), f_input):
header = [cols.strip() for cols in next(csv.reader(StringIO.StringIO(line), delimiter='|', skipinitialspace=True))][1:-1]
break
with open('input.txt', 'rb') as f_input, open('output.csv', 'wb') as f_output:
csv_output = csv.writer(f_output)
csv_output.writerow(header)
for line in itertools.ifilter(lambda x: len(x) > 2 and x[0] == '|' and x[1] != '-' and not x[1].isalpha(), f_input):
csv_input = csv.reader(StringIO.StringIO(line), delimiter='|', skipinitialspace=True)
csv_output.writerow([col.strip().translate(None, ",!.;") for col in next(csv_input)[1:-1]])
这将为您提供如下输出 csv 文件:
Mat. Doc.,MatYr,MvT,Material,Plnt,SLoc,Batch,Customer,Amount in LC,Amount,Quantity,BUn,Qty in UnE,EUn,PO,MatYr,Mat. Doc.,Order,Profit Ctr,SLED/BBD,Pstng Date,Entry Date,Time,User name
4912693062,2015,551,100062,HDC2,0001,5G30MC1A11,,903,906,0083,CS,2,EA,,,,,IN1165B085,26012016,01082015,01082015,01:13:16,O33462
4912693063,2015,501,166,HDC2,0004,,,000,000,2,EA,2,EA,,,,,IN1165B085,,01082015,01082015,01:13:17,O33462
4912693320,2015,551,101343,HDC2,0001,5G28MC1A11,,5373,5372,0500,CS,12,EA,,,,,IN1165B085,25012016,01082015,01082015,01:16:30,O33462
4912696602,2015,344,100399,HMH3,0001,5G29MH3S11,,000,000,9061,CS,9061,CS,,,,,IN1165B074,26012016,01082015,01082015,01:54:15,A70475
【讨论】:
你在第四行得到了“”。该文件不应包含任何 ,因为在解析它时会出现 EOF 错误。 如果列包含逗号,CSV 格式会自动添加引号,否则将被解释为另一列。您可以强制引用所有列,但要抑制它们,您需要解析逗号。此文件将按原样正确加载到 Excel 中。 如果可能的话,您能否在顶部添加一行标题。 如果我们的 csv 文件中有"
,那么在将文件解析为 pandas 时会出现此错误:CParserError: Error tokenizing data. C error: Expected 1 fields in line 73685, saw 4
感谢您的回答,但还有一个请求您的第一个程序已正确解析。对此感到抱歉,但您没有从给我错误的行中删除"
或'
。感谢您的解决方案。如果可能的话,你能告诉我我应该改变什么,以便脚本将删除"
和'
并在顶部添加一组标题。我得到的错误在第 73685 行,因为有 "
。谢谢【参考方案2】:
这里是基于How to convert a SAP .txt extraction into a .csv file中答案的方法,不需要打开输入文件两次。
这是来自该答案的代码,使用 @Martin Evans 的巧妙技术测试 row[1].isalpha
以确定您是否有标题,并且只导出一次:
import csv
ii = 0
with open('file.txt', 'r', encoding='utf8', newline='') as f_input, \
open(str(ii + 1) + 'output.csv', 'w', encoding='utf8', newline='') as f_output:
input_lines = filter(lambda x: len(x) > 2 and x[0] == '|' and x[1] == ' ', f_input)
csv_input = csv.reader(input_lines, delimiter='|')
csv_output = csv.writer(f_output)
found_header = False
for row in csv_input:
if not found_header and row[1].isalpha():
found_header = True
csv_output.writerow(col.strip() for col in row[1:-1])
【讨论】:
以上是关于我有一个 SAP 生成的文件,其中包含许多列和一些不需要的行。我应该如何直接读入 Pandas?的主要内容,如果未能解决你的问题,请参考以下文章