[英]Parse text file and convert to csv
我需要将一个大文本文件转换为 csv 文件,同时解析文本并仅获取创建新表所需的信息。 这就是我所拥有的:
# -- name1 --
country: Italy
age:30
height: 1,8
weight: 80
# -- name2 --
age:20
height: 1,6
weight: 50
# -- name3 --
City: Berlin
country: Italy
age:33
height: 1,7
weight: 82
而我需要的 output 是:
Name Age Height
name1 30 1,8
name2 20 1,6
name3 33 1,7
我想使用 Pandas 是可行的,但我在开始编码时遇到了一些困难。 你能帮我解决这个问题吗? 谢谢。
您也可以不使用 pandas 来做到这一点。
with open('res.txt') as file:
contents = file.read().split('\n')
name,age,height = [],[],[]
for ele in contents:
if ele.__contains__('#'):
lis = [name if name!='#' and name!='--' else '' for name in ele.split()]
name.append(' '.join(lis))
elif ele.__contains__('age'):
age.append(ele.split(':')[1])
elif ele.__contains__('height'):
height.append(ele.split(':')[1])
with open('output_csv.csv','a') as file:
file.write('Name,Age,Height\n')
for ele in list(zip(name,age,height)):
file.write(f'"{ele[0]}",{ele[1]},"{ele[2]}"\n')
上一个答案需要手动添加所有键,并忽略国家和城市的键值对。
如果您想使用 pandas,您不妨执行以下操作:
import re
import pandas as pd
# Create empty list to store dicts for every block
dict_list = []
# Split string into blocks using the comment at the beginning
blocks = re.split('#.*--', string)
# Iterate over all blocks
for block in blocks:
# Use regex to find all key-value pairs, assuming they are split by
# either ':' or ': '.
tuples = re.findall('(.*):\s?(.*)', block)
# Create an empty dictionary to convert the list of tuples
# returned by findall
d = {}
# Iterate over all tuples in list
for t in tuples:
# Create a key-value pair from the tuple
d[t[0].lower()] = t[1]
if tuples:
# Append the dictionary to dict_list
dict_list.append(d)
# Create a data frame from the list of dicts.
df = pd.DataFrame(dict_list)
一般的挑战是您的数据是键值对的形式,而不是pd.read_csv()
可以处理的表格格式。 假设它实际上不是.yaml
文件(然后只需使用pyyaml
并从 dict 创建数据框),您需要解析文件。
请参阅内联评论以获得进一步的解释。
没那么难,但它需要一个自定义解析器。
规则:
#
) 开头的行开头
# -- name --
:名称是拆分时的第二个字段--
:
)代码可以是:
with open('file.txt') as fdin, open('file.csv', newline='') as fdout:
wr = csv.DictWriter(fdout, fieldnames=['Name', 'Age', 'Height'],
extrasaction='ignore') # ignore unwanted fields
row = {}
wr.writeheader() # write the header line
for line in fdin:
if line.startswith('#'): # process a name line
name = line.split('--')[1].strip()
if len(row) != 0: # if we have a row write it
wr.writerow(row)
row = {'Name': name} # initialize a new row
else:
field, value = line.split(':') # process a field line
row[field.strip().capitalize()] = value.strip()
if len(row) != 0: # do not forget the last row
wr.writerow(row)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.