我有一个以下格式的大文本文件,我希望将其转换为CSV文件。 CSV文件中的列名称应与下面看到的元组的第一部分相对应。可以安全地假设该行中的第一个项目(不是元组)将始终采用以下格式。
其他问题包括每一行可能没有相同的字段 - 例如,某些字段有状态,有些则没有。有些人有同一领域的多个实例,在这种情况下,我要求连接元组的第二部分(例如,给史密斯先生;格林夫人),但这些问题现在还有一些问题。
[' Message 1 '];['Status', 'Read'];['Message ID', '012434'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2010 05:56:36']
[' Message 2 '];['ColumnName', 'Read'];['ColumnName2', '012434'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2010 05:56:36']
[' Message 3 '];['To', 'Mr Smith'];['To', 'Mrs green'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2013 05:56:36']
...
我的计划是遍历文件中的每个块以建立列名,然后开始向这些列名添加数据,并在适当时留下空白。我只是想知道如何以pythonic的方式解决这个问题,因为我已经玩了一系列词典并被卡住了。
我想我需要拆分该行,然后将每个元组添加到字典中。有帮助吗? 谢谢!
for line in file:
line_split = line.split(';')
答案 0 :(得分:4)
您可以使用ast.literal_eval
将每个['something', 'something_else']
块转换为python列表:
import ast
column_ids = set()
for line in file:
columns = [tuple(ast.literal_eval(c)) for c in line.split(';')]
columns[0] = ('id', columns[0][0]) # Give the first column a 'Id' key
columns = dict(columns) # turn the row into a dict
column_ids.update(columns)
添加print语句并使用示例输入,结果为:
{'Status': 'Read', 'Sent Time': '15/12/2010 05:56:36', 'Message Truncation': 'OK', 'Message ID': '012434', 'Priority': 'Low', 'id': ' Message 1 '}
{'Sent Time': '15/12/2010 05:56:36', 'ColumnName2': '012434', 'Message Truncation': 'OK', 'Priority': 'Low', 'ColumnName': 'Read', 'id': ' Message 2 '}
{'Message Truncation': 'OK', 'To': 'Mrs green', 'Priority': 'Low', 'id': ' Message 3 ', 'Sent Time': '15/12/2013 05:56:36'}
和column_ids
是:
set(['Status', 'Priority', 'ColumnName', 'Message Truncation', 'Message ID', 'To', 'Sent Time', 'ColumnName2', 'id'])
答案 1 :(得分:1)
使用纯python的解决方案...
infile = "listdata.txt"
data = open(infile, "r").readlines()
dataDict = []
columns = []
# Create a dictionary list
for line in data:
row = line.split(";");
rowData = {}
for cell in row:
cell = cell.strip()[1:-1].split(",")
if len(cell) > 1:
rowData[cell[0].strip().strip('"').strip("'")] = cell[1].strip().strip('"').strip("'")
keys = rowData.keys()
dataDict.append(rowData)
columns = list(set(columns) | set(keys))
# Write dictionary list to file
outfile = "listdata.csv"
fp = open(outfile, "w")
for key in columns:
fp.write(key + ", ")
fp.write("\n")
for data in dataDict:
for key in columns:
if key in data:
fp.write(data[key] + ",")
else:
fp.write(",")
fp.write("\n")
fp.close()
输入:
[' Message 1 '];['Status', 'Read'];['Message ID', '012434'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2010 05:56:36']
[' Message 2 '];['ColumnName', 'Read'];['ColumnName2', '012434'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2010 05:56:36']
[' Message 3 '];['To', 'Mr Smith'];['To', 'Mrs green'];['Message Truncation', 'OK'];['Priority', 'Low'];['Sent Time', '15/12/2013 05:56:36']
输出:
Status, Sent Time, To, ColumnName2, Message ID, Message Truncation, Priority, ColumnName,
Read,15/12/2010 05:56:36,,,012434,OK,Low,,
,15/12/2010 05:56:36,,012434,,OK,Low,Read,
,15/12/2013 05:56:36,Mrs green,,,OK,Low,,
<强>更新强>
这会处理多个具有相同类型的条目,然后使用":"
加入。
key = cell[0].strip().strip('"').strip("'")
value = cell[1].strip().strip('"').strip("'")
if key in rowData:
rowData[key] = rowData[key] + ":" + value
else:
rowData[key] = value
答案 2 :(得分:1)
使用pandas:
from pandas import *
import ast
from itertools import chain
df=read_csv('in.txt',sep=';',header=None).applymap(ast.literal_eval).ix[:,1:]
newdf=DataFrame(columns=set(i[0] for i in chain(*df.values)),index=df.index)
for row in df.iterrows():
for c in row[1].values:
newdf[c[0]][row[0]]=c[1]
newdf.to_csv('out.csv')