【问题标题】:Extract text files into multiple columns in python在python中将文本文件提取到多个列中
【发布时间】:2016-07-29 21:47:53
【问题描述】:

我有不同的文本文件,我想将其中的值提取到 csv 文件中。 每个文件的格式如下

main cost: 30
additional cost: 5

我设法做到了,但问题是我希望它将每个文件的值插入到不同的列中,我还希望文本文件的数量成为用户参数

这就是我现在正在做的事情

  numFiles = sys.argv[1]
  d = [[] for x in xrange(numFiles+1)]
  for i in range(numFiles): 
      filename = 'mytext' + str(i) + '.text'
      with open(filename, 'r') as in_file:
      for line in in_file:
        items = line.split(' : ')
        num = items[1].split('\n')

        if i ==0:
            d[i].append(items[0])

        d[i+1].append(num[0])

        grouped = itertools.izip(*d[i] * 1)
        if i == 0:
            grouped1 = itertools.izip(*d[i+1] * 1)

        with open(outFilename, 'w') as out_file:
            writer = csv.writer(out_file)
            for j in range(numFiles):
                for val in itertools.izip(d[j]):
                    writer.writerow(val)

这就是我现在得到的,一列中的所有内容

main cost   
additional cost   
30   
5   
40   
10

我希望它是

main cost        | 30  | 40
additional cost  | 5   | 10

【问题讨论】:

  • 你试过使用元组吗?
  • 所需输出中的最后一列来自哪里?每个输入文件中是否只有两行?
  • 我假设输入文件看起来像: 主要成本:30 额外成本:5 主要成本:40 额外成本:10
  • 啊...,所以每个文件都是一个新列。
  • @wwii 是的,正如迈克尔所说的

标签: python csv extract multiple-columns


【解决方案1】:

您可以使用字典来执行此操作,其中键是您要使用的“标题”,值是列表。

所以它看起来像someDict = {'main cost': [30,40], 'additional cost': [5,10]}

edit2:继续清理这个答案,让它更有意义。

您可以像这样构建字典并对其进行迭代:

from collections import OrderedDict

in_file = ['main cost : 30', 'additional cost : 5', 'main cost : 40', 'additional cost : 10']
someDict = OrderedDict()

for line in in_file:
    key,val = line.split(' : ')
    num = int(val)
    if key not in someDict:
        someDict[key] = []

    someDict[key].append(num)

for key in someDict:
    print(key)
    for value in someDict[key]:
        print(value)

代码输出:

main cost
30
40
additional cost
5
10

修改示例以适合您所需的输出应该非常简单。

我使用了@append multiple values for one key in Python dictionary 的例子,感谢@wwii 的一些建议。

我使用了OrderedDict,因为字典不会按顺序保存键。

你可以运行我的例子@https://ideone.com/myN2ge

【讨论】:

  • 对于这个解决方案,您可以确保只有两个键,因此您可以使用这两个键和一个空值列表预先构建字典 - 然后您可以摆脱if/else 用于字典分配。或者,如果您事先不确定密钥,您可以使用collections.defaultdict。
  • 当您拆分文本并计划稍后在代码中使用各个项目时,最好给它们命名 - 这会使后续代码更易于阅读。利用拆包:在这种情况下,例如 - key, value = line.split(':') ; value = value.strip()
  • 两个很好的例子。首先,我可能会保持这种方式,以便将来可以更改文件格式而无需修改代码。我同意你的第二个例子。
  • 玩转collections.defaultdict,它解决了在不使用if/thens 或try/excepts 的情况下尝试分配缺失键的问题。
  • 除非您想使用 OrderedDict,否则这也可以,这可能是 OP 想要的。否则,它不会总是以相同的顺序输出。不过,我将编辑我的示例以包含您的第一个建议。这样阅读起来要容易得多。
【解决方案2】:

我可能会这样做。假设所有文件中的字段都相同。制作一个名称列表和一个使用这些字段名称作为键的字典,并将值列表作为条目。不要在file1.text、file2.text 等上运行,而是使用file*.text 作为命令行参数运行脚本。

#! /usr/bin/env python

import sys

if len(sys.argv)<2:
    print "Give file names to process, with wildcards"
else:
    FileList= sys.argv[1:]
    FileNum = 0
    outFilename = "myoutput.dat"
    NameList = []
    ValueDict = {}
    for InfileName in FileList:
        Infile = open(InfileName, 'rU') 
        for Line in Infile: 
            Line=Line.strip('\n')
            Name,Value = Line.split(":")
            if FileNum==0:
                NameList.append(Name.strip())
            ValueDict[Name] = ValueDict.get(Name,[]) + [Value.strip()]
        FileNum += 1 # the last statement in the file loop
        Infile.close()
    # print NameList
    # print ValueDict

    with open(outFilename, 'w') as out_file:
        for N in NameList:
            OutString =  "{},{}\n".format(N,",".join(ValueDict.get(N)))
            out_file.write(OutString)

我的四个假文件的输出是:

main cost,10,10,40,10
additional cost,25.6,25.6,55.6,25.6

【讨论】:

  • 感谢@beroe,但我希望将输出保存在 csv 文件中,| 代表不同的列
  • 这是我尝试上述代码时得到的结果 TypeError: can only join an iterable
  • 插入一行打印 ValueDict 并查看它的内容。如果数据与您的示例匹配,则每个值都应该是字符串(数字)列表。如果有空行或标题行,您可以在ValueDict[Name]= 部分之前在循环中插入一个检查...
猜你喜欢
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-09
  • 2012-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多