【问题标题】:Transform tagged to CSV转换标记为 CSV
【发布时间】:2013-01-21 15:47:49
【问题描述】:

这样的文件:

fieldname_A: eggs
fieldname_B: bacon 
~EOR~
..
..
~EOR~
fieldname_A: eggs
fieldname_C: spam
fieldname_Z: baked beans
~EOR~

总共有 40 个不同的字段名称,大约 10,000 条记录(EOR 是 End Of Record),其中包含一组可变的字段。大多数字段内容很短,有些很长(超过 1000 个字符)。

我正在寻找一种漂亮、干净、pythonic 的方式来将其转换为 CSV,或者更确切地说,转换为 Google 电子表格。 (数据需要检查和更正。有几个人会这样做。我知道谷歌文档是他们处理相同数据而不会导致版本冲突或同步问题的唯一快速方法。)

Dictwriter 似乎是一种繁琐的方式,因为许多记录(即电子表格中的行)中的字段为空。

输入文件的格式更像 XML,所以我想将其转换为 XML,将其导入 Excel,然后将其作为 Google 电子表格上传。

有什么想法吗?

【问题讨论】:

  • 字段名称是预先知道的吗?
  • DictWriter 可以被告知对连续丢失的条目使用默认值。
  • 最后但并非最不重要的一点是,一个记录结束行有~EOR,而所有其他行都有~EOR~(注意第二个波浪号)。这是你的错字吗?
  • @Martijn 是的,字段名称是预先知道的;输入 ~EOR~ 已更正,谢谢 :-) ;是的,您假设没有数据行中包含 EOR 是正确的。
  • 为了您的数据清理,请调查“Google Refine”(现在显然已重命名为“OpenRefine”)。

标签: python xml csv


【解决方案1】:

使用这个...

infile = "d.txt"
data = open(infile, "r").readlines()

dataDict = []
columns = []

rowData = {}
# Create a dictionary list
for line in data:
    if not line.strip():
        continue
    if "~EOR~" in line:
        keys = rowData.keys()
        dataDict.append(rowData)
        columns = list(set(columns) | set(keys))
        rowData = {}
    else:  
        cell = line.split(":", 1);
        print cell
        rowData[cell[0].strip().strip('"').strip("'")] = cell[1].strip().strip('"').strip("'")


# Write dictionary list to file
outfile = "d.csv"

with open(outfile, "w") as fp:

    columns.sort()

    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")

输入:

fieldname_A: eggs
fieldname_B: bacon 
~EOR~
fieldname_A: eggs
fieldname_C: spam
fieldname_Z: baked beans
~EOR~

输出:

fieldname_A, fieldname_B, fieldname_C, fieldname_Z, 
eggs,bacon,,,
eggs,,spam,baked beans,

【讨论】:

  • 使用.split(':', 1) 仅在第一个冒号上拆分;这样值可以在其中有一个冒号并且仍然是可解析的。空行很容易跳过..if not line.strip(): continue.
  • 测试line.strip() == '~EOF~' 应该不难,当然,去掉最后一个假设。然后假设 ~EOF 没有尾随波浪号是问题中的错误,而不是文件格式的正确示例。或测试line.strip() in ('~EOF', '~EOF~')..
  • @MartijnPieters 非常感谢!我会试试这个。会让你知道结果
  • @AToxTOA 也非常感谢!
  • @all 伙计们,你们都很可爱,它就像一个魅力。我把分隔符变成了一个管道,因为很多行都包含逗号和分号。我也喜欢微妙的“打印单元”。一些领域结果证明有四倍的硬回报。无论如何我都需要更换那些(做过单,双和三)。拆分将在违规行上崩溃。
猜你喜欢
  • 1970-01-01
  • 2019-04-18
  • 1970-01-01
  • 2018-01-03
  • 2012-04-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
相关资源
最近更新 更多