在python中将空格分隔文件转换为逗号分隔值文件

Posted

技术标签:

【中文标题】在python中将空格分隔文件转换为逗号分隔值文件【英文标题】:Convert a space delimited file to comma separated values file in python 【发布时间】:2013-11-14 13:57:45 【问题描述】:

我对 Python 很陌生。我知道这已经被问过了,我很抱歉,但是这种新情况的不同之处在于字符串之间的空格不相等。我有一个名为 coord 的文件,其中包含以下空格分隔的字符串:

   1  C       6.00    0.000000000    1.342650315    0.000000000
   2  C       6.00    0.000000000   -1.342650315    0.000000000
   3  C       6.00    2.325538562    2.685300630    0.000000000
   4  C       6.00    2.325538562   -2.685300630    0.000000000
   5  C       6.00    4.651077125    1.342650315    0.000000000
   6  C       6.00    4.651077125   -1.342650315    0.000000000
   7  C       6.00   -2.325538562    2.685300630    0.000000000
   8  C       6.00   -2.325538562   -2.685300630    0.000000000
   9  C       6.00   -4.651077125    1.342650315    0.000000000
  10  C       6.00   -4.651077125   -1.342650315    0.000000000
  11  H       1.00    2.325538562    4.733763602    0.000000000
  12  H       1.00    2.325538562   -4.733763602    0.000000000
  13  H       1.00   -2.325538562    4.733763602    0.000000000
  14  H       1.00   -2.325538562   -4.733763602    0.000000000
  15  H       1.00    6.425098097    2.366881801    0.000000000
  16  H       1.00    6.425098097   -2.366881801    0.000000000
  17  H       1.00   -6.425098097    2.366881801    0.000000000
  18  H       1.00   -6.425098097   -2.366881801    0.000000000

请注意第一列中每个字符串开头之前的空格。所以我尝试了以下将其转换为 csv 的顺序:

with open('coord') as infile, open('coordv', 'w') as outfile:
    outfile.write(infile.read().replace("  ", ", "))

# Unneeded columns are deleted from the csv

input = open('coordv', 'rb')
output = open('coordcsvout', 'wb')
writer = csv.writer(output)
for row in csv.reader(input):
    if row:
        writer.writerow(row)
input.close()
output.close()

with open("coordcsvout","rb") as source:
    rdr= csv.reader( source )
    with open("coordbarray","wb") as result:
        wtr= csv.writer(result)
        for r in rdr:
            wtr.writerow( (r[5], r[6], r[7]) )

当我运行脚本时,我在脚本的第一部分得到以下 coordv,这当然是非常错误的:

,  1, C, , ,  6.00, , 0.000000000, , 1.342650315, , 0.000000000
,  2, C, , ,  6.00, , 0.000000000,  -1.342650315, , 0.000000000
,  3, C, , ,  6.00, , 2.325538562, , 2.685300630, , 0.000000000
,  4, C, , ,  6.00, , 2.325538562,  -2.685300630, , 0.000000000
,  5, C, , ,  6.00, , 4.651077125, , 1.342650315, , 0.000000000
,  6, C, , ,  6.00, , 4.651077125,  -1.342650315, , 0.000000000
,  7, C, , ,  6.00,  -2.325538562, , 2.685300630, , 0.000000000
,  8, C, , ,  6.00,  -2.325538562,  -2.685300630, , 0.000000000
,  9, C, , ,  6.00,  -4.651077125, , 1.342650315, , 0.000000000
, 10, C, , ,  6.00,  -4.651077125,  -1.342650315, , 0.000000000
, 11, H, , ,  1.00, , 2.325538562, , 4.733763602, , 0.000000000
, 12, H, , ,  1.00, , 2.325538562,  -4.733763602, , 0.000000000
, 13, H, , ,  1.00,  -2.325538562, , 4.733763602, , 0.000000000
, 14, H, , ,  1.00,  -2.325538562,  -4.733763602, , 0.000000000
, 15, H, , ,  1.00, , 6.425098097, , 2.366881801, , 0.000000000
, 16, H, , ,  1.00, , 6.425098097,  -2.366881801, , 0.000000000
, 17, H, , ,  1.00,  -6.425098097, , 2.366881801, , 0.000000000
, 18, H, , ,  1.00,  -6.425098097,  -2.366881801, , 0.000000000

我在 .replace 中尝试了不同的可能性,但没有成功,到目前为止,我还没有找到任何关于如何做到这一点的信息来源。从此 coord 文件中获取逗号分隔值的最佳方法是什么?我感兴趣的是在 python 中使用 csv 模块来选择 4:6 列,最后使用 numpy 导入它们,如下所示:

from numpy import genfromtxt
cocmatrix = genfromtxt('input', delimiter=',')

如果有人能帮我解决这个问题,我会很高兴。

【问题讨论】:

sed -r 's/^\s+//;s/\s+/,/g' coord 如果唯一的目的只是从一种类型转换为另一种类型,那么 bash 脚本会很容易,对吧? 我知道如何使用 sed、awk、bash 脚本等。但是,我的目的不仅仅是从一种类型的文件转换为另一种类型的文件。我正在处理来自量子化学程序的输出文件以执行一些操作,以便在考虑局部分子轨道的电荷中心的基础上自动化以后的大量计算。 它看起来像一个固定宽度的文件(设置位置的字段)。这是关于固定宽度的问题:***.com/questions/4914008/…,或者您可以使用切片将其拆分***.com/questions/509211/pythons-slice-notation 【参考方案1】:

用这个替换你的第一个位。 它不是超级漂亮,但它会给你一个 csv 格式。

with open('coord') as infile, open('coordv', 'w') as outfile:
    for line in infile:
        outfile.write(" ".join(line.split()).replace(' ', ','))
        outfile.write(",") # trailing comma shouldn't matter

如果您希望 outfile 将所有内容放在不同的行上,您可以添加 outfile.write("\n") 在 for 循环的末尾,但我认为您的代码不会像这样使用它。

【讨论】:

您是否实际测试过该代码?输入文件具有多个空格序列,这些空格转换为空字段序列,即第一行的['', '', '', '1', '', 'C', '', '', '', '', '', '', '6.00', '', '', '', '0.000000000', '', '', '', '1.342650315', '', '', '', '0.000000000']。 -1 因为它不起作用。 我知道确实如此,这就是我建议换行符的原因。 对不起,我错过了,虽然我认为作者的意图很明确。我已经删除了 -1。 我想补充一点,这个答案更笼统。我现在改用它作为这个问题的答案。【参考方案2】:

你可以使用 csv:

import csv

with open(ur_infile) as fin, open(ur_outfile, 'w') as fout:
    o=csv.writer(fout)
    for line in fin:
        o.writerow(line.split())

【讨论】:

注意.strip()在这里是多余的; line.split() 已经这样做了。 @thewolf 为每行打印一个额外的空行(否则效果很好)...知道为什么会发生这种情况吗?【参考方案3】:

您可以使用python pandas,我已将您的数据写入data.csv

import pandas as pd
>>> df = pd.read_csv('data.csv',sep='\s+',header=None)
>>> df
     0  1  2         3         4  5
0    1  C  6  0.000000  1.342650  0
1    2  C  6  0.000000 -1.342650  0
2    3  C  6  2.325539  2.685301  0
3    4  C  6  2.325539 -2.685301  0
4    5  C  6  4.651077  1.342650  0
5    6  C  6  4.651077 -1.342650  0
...

这样做的好处是可以访问您可以使用的底层 numpy 数组df.values

>>> type(df.values)
<type 'numpy.ndarray'>

使用逗号分隔符保存数据框:

>>> df.to_csv('data_out.csv',header=None)

Pandas 是一个用于管理大量数据的出色库,此外它还可以与 numpy 配合使用。这也很有可能比使用 csv 模块快得多。

【讨论】:

【参考方案4】:

为什么不逐行读取文件?将一行拆分为一个列表,然后用 ',' 重新加入一个列表。

【讨论】:

给我们看一些代码。除此之外,这已经是suggested by the wolf。【参考方案5】:
>>> a = 'cah  1  C       6.00    0.000000000    1.342650315    0.000000000'
=>  a = 'cah  1  C       6.00    0.000000000    1.342650315    0.000000000'

>>> a.split()
=>  ['cah', '1', 'C', '6.00', '0.000000000', '1.342650315', '0.000000000']

>>> ','.join(a.split())
=>  'cah,1,C,6.00,0.000000000,1.342650315,0.000000000'

>>> ['"' + x + '"' for x in a.split()]
=>  ['"cah"', '"1"', '"C"', '"6.00"', '"0.000000000"', '"1.342650315"', '"0.000000000"']

>>> ','.join(['"' + x + '"' for x in a.split()]
=>  '"cah","1","C","6.00","0.000000000","1.342650315","0.000000000"'

【讨论】:

【参考方案6】:

csv 模块很好,或者这里有一种方法可以不用:

#!/usr/local/cpython-3.3/bin/python

with open('input-file.csv', 'r') as infile, open('output.csv', 'w') as outfile:
    for line in infile:
        fields = line.split()
        outfile.write('\n'.format(','.join(fields)))

【讨论】:

【参考方案7】:

用于将“空格”转换为“,”

只填写你想要的文件名

with open('filename') as infile, open('output', 'w') as outfile:
    outfile.write(infile.read().replace(" ", ","))

用于将“,”转换为“空格”

with open('filename') as infile, open('output', 'w') as outfile: outfile.write(infile.read().replace(",", " "))

【讨论】:

【参考方案8】:

用于在一个 CSV 中合并多个文本文件

import csv
import os
for x in range(0,n):            #n = max number of files 
    with open('input.txt'.format(x)) as fin, open('output.csv', 'a') as fout:
       csv_output=csv.writer(fout)
       for line in fin:
            csv_output.writerow(line.split())

【讨论】:

以上是关于在python中将空格分隔文件转换为逗号分隔值文件的主要内容,如果未能解决你的问题,请参考以下文章

在 Python 3 中将逗号分隔的字符串转换为 Numpy 数组

如何将同时具有逗号和空格分隔符的 CSV 文件转换为只有空格分隔符的 csv

如何在oracle中将值列表转换为逗号分隔值

如何在 Azure Databricks SQL 中将字段值转换为逗号分隔

打开用空格分隔符保存为逗号分隔符的CSV文件[关闭]

在mysql中将分隔字符串转换为多个值