python - 无法推断 CSV 文件的架构
问题描述
我在 file1.dat 文件中获取数据,数据由 | 分隔 特点。
109|LK98765|2|18.07.2021|01|abc1|01|abc2|01|abc3
110|LK67665|2|10.10.1987|02|abc1|01|abc2|01|abc3
111|LK43465|2|23.07.2005|03|abc1|01|abc2|01|abc3
112|LK23265|2|13.02.2012|04|abc1|01|abc2|01|abc3
我的要求是在文件中添加标题并将其更改为 .csv,字段分隔符为 ,。
为了达到上述要求,下面的代码是用python编写的。
添加标题:
def fn_add_header(file_name):
with(open(file_name) as f:
r=csv.reader(f)
data = line [line for line in r]
with(open(file_name,'wb') as f:
w =csv.writer(f)
w.writerow(['ID','SEC_NO','SEC_CD','SEC_DATE','SEC_ID1','SEC_DESC1','SEC_ID2','SEC_DESC2','SEC_ID3','SEC_DESC3'])
w.writerows(data)
要将文件更改为 csv:
def fn_replace(filename,directory)
final_file = directory+"\file1.csv"
for file in os.listdir(filename)
if fnmatch.fnmatch(file.lower(),filename.lower()):
shutil.copyfile (file,final_file )
cmd = ["sed","-i","-e"'s/|/,/g',final_file )
ret2,out2,err2 = fn_run_cmd(cmd)
上面的代码工作正常,我得到转换后的文件:
ID,SEC_NO,SEC_CD,SEC_DATE,SEC_ID1,SEC_DESC1,SEC_ID2,SEC_DESC2,SEC_ID3,SEC_DESC3
109,LK98765,2,18.07.2021,01,abc1,01,abc2,01,abc3
110,LK67665,2,10.10.1987,02,abc1,01,abc2,01,abc3
111,LK43465,2,23.07.2005,03,abc1,01,abc2,01,abc3
112,LK23265,2,13.02.2012,04,abc1,01,abc2,01,abc3
我在 yml 中读取上述转换后的 file.csv 时遇到问题。要阅读我正在使用以下代码的文件:
frameworkComponents:
today_file:
inputDirectoryPath: <path of the file>
componentName: today_file
componentType: inputLoader
hadoopfileFormat: csv
csvSep: ','
selectstmt:
componentName: selectstmt
componentType: executeSparlSQL
sql: |-
select ID,SEC_NO,
SEC_CD,SEC_DATE,
SEC_ID1,SEC_DESC1,
SEC_ID2,SEC_DESC2,
SEC_ID3,SEC_DESC3
from today_file
write_file:
componentName: write_file
componentType: outputWriter
hadoopfileFormat: avro
numberofPartition: 1
outputDirectoryPath: <path of the file>
precedence:
selectstmt:
dependsOn:
today_file: today_file
write_file:
dependsOn:
selectstmt: selectstmt
当我运行 yml 时,我遇到了错误。
Unable to infer schema for CSV. It must be specified manually.
解决方案
您的函数fn_add_header
有一些语法错误,例如 ; 中的不平衡括号with
。声明data = line [line for line in r]
(可能你想做一个列表理解,但它应该是data = [line for line in r]
);你定义写一个byte
对象,但读写应该是一个text
对象。
fn_add_header
您应该按如下方式重写该函数。请注意,在读取要定义的数据文件时delimiter='|'
,以及在编写新的 CSV 文件时需要定义,newline=''
否则它将为每一行添加一个额外的行。
import csv
def fn_add_header(file_name):
with open(file_name, 'rt') as f:
r = csv.reader(f, delimiter='|')
data = [line for line in r]
new_file_name = file_name[:-4] + '.csv'
with open(new_file_name, 'wt', newline='') as f:
w = csv.writer(f)
w.writerow(['ID','SEC_NO','SEC_CD','SEC_DATE','SEC_ID1','SEC_DESC1','SEC_ID2','SEC_DESC2','SEC_ID3','SEC_DESC3'])
w.writerows(data)
fn_add_header('doodle_data.dat')
doodle_data.dat
109|LK98765|2|18.07.2021|01|abc1|01|abc2|01|abc3
110|LK67665|2|10.10.1987|02|abc1|01|abc2|01|abc3
111|LK43465|2|23.07.2005|03|abc1|01|abc2|01|abc3
112|LK23265|2|13.02.2012|04|abc1|01|abc2|01|abc3
doodle_data.csv
ID,SEC_NO,SEC_CD,SEC_DATE,SEC_ID1,SEC_DESC1,SEC_ID2,SEC_DESC2,SEC_ID3,SEC_DESC3
109,LK98765,2,18.07.2021,01,abc1,01,abc2,01,abc3
110,LK67665,2,10.10.1987,02,abc1,01,abc2,01,abc3
111,LK43465,2,23.07.2005,03,abc1,01,abc2,01,abc3
112,LK23265,2,13.02.2012,04,abc1,01,abc2,01,abc3
最后,您应该调用该函数,convert_and_add_header
因为它实际上正在执行此操作。
推荐阅读
- python - Django rest 框架:从外部包中捕获 ValidationError
- javascript - Angular ng-repeat 表:来自对象的动态列
- angular - Angular Cli 错误:位置 1008 的 JSON 中的意外标记]
- java - 如何在运行时从数据库动态加载身份提供者 (IdP) Sprint Security SAML
- python - IntelliJ 无法导入模块,但从命令行可以正常工作
- r - 更新输入函数包
- javascript - 移动响应式下拉导航栏适用于小宽度浏览器,但不适用于我的手机
- regex - 不匹配某些字符串的正则表达式
- json - 替换 PostgreSQL 9.6 中的第一个和最后一个 JSON 字符
- javascript - 在元素中包裹 iframe