将混合格式.DAT转换为.CSV(或其他任何内容)

时间:2016-10-26 18:02:25

标签: python csv

我有大量需要转换的DAT文件(最终转换为唯一的文件类型)。 DAT在字段之间具有混合的空白量,列标题在不同的行上。有什么建议吗?

                    ALT_RAD
                                               ALT_RAD2
                 DIRECT        D_GLOBAL        U_GLOBAL          Zenith
Year Mn Dy Hr Mi        DIFFUSE2            D_IR            U_IR
2004  9  1  0  1    1.04   79.40   78.67  303.58   61.06  310.95  85.142
2004  9  1  0  2    0.71   74.36   73.91  303.80   57.82  310.92  85.171
2004  9  1  0  3    0.67   71.80   71.64  304.25   56.84  310.98  85.199
2004  9  1  0  4    0.75   74.35   74.83  304.21   59.68  310.89  85.227

我有一个基本的脚本:

import sys
with open(sys.argv[1], r) as input_file:
    newLines = []
    for line in input_file:
            newLines.append(newLine)

我肯定会更改为混合空格,但我不知道如何使用不稳定的列标题。

最终我希望我的标题只是:

Year Month Day Hour Minute Direct Diffuse2 D_Global D_IR U_Global U_IR Zenith

3 个答案:

答案 0 :(得分:3)

将输入文件中的标题行视为他们应得的所有蔑视。 (换句话说,阅读并弃掉它们。)

headers='Year Month Day Hour Minute Direct Diffuse2 D_Global D_IR U_Global U_IR Zenith'
with open ( 'temp.dat') as input_file:
    with open ('temp_2.csv', 'w') as output_file:
        output_file.write('"%s"\n'%'","'.join(headers.split()))
        for count, line in enumerate(input_file):
            if count<4: continue
            outLine = ','.join(line.split())
            output_file.write(outLine + '\n')

答案 1 :(得分:1)

这是&#34; Python的答案 - 下载并将.dat转换为.csv [复制]&#34;。我无法在那里发帖,因此,你可以从这里得到确切的输出。

import urllib2
import csv
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/auto-mpg/auto-mpg.data'
response = urllib2.urlopen(url)
readData = response.read()
strObj = filter(None,readData.splitlines())

strObj = [w.replace('\t', '  ') for w in strObj]

listB = []
for i in strObj:
    listB.append(filter(None,i.split("  ")))
with open(r'c:/data2.csv','a') as f:
    writer = csv.writer(f)
    writer.writerows(listB)

答案 2 :(得分:1)

看起来您可以根据单词在该行中的位置动态组合标题行。您可以跳过前两行,并合并后两行。如果你做得对,你将在文件流上留下一个迭代器,你可以用它来处理你想要的其余数据。您可以将其转换为其他格式,甚至可以直接将其导入到pandas DataFrame中。

获取标题:

import re

def get_words_and_positions(line):
    return [(match.start(), match.group()) in re.finditer(r'[\w.]+', line)]

with open('file.dat') as file:
    iterator = iter(file)
    # Skip two lines
    next(iterator)
    next(iterator)
    # Get two header lines
    header = get_words_and_positions(next(iterator)) + \
             get_words_and_positions(next(iterator))
    # Sort by positon
    header.sort()
    # Extract words
    header = [word for pos, word in header]

您现在可以将文件转换为真实的CSV,或使用它执行其他操作。这里重要的是你有iterator指向文件流中的实际数据,以及一堆动态加载的列标题。

要将余数写入CSV文件,而不必一次将整个内容加载到内存中,请使用csv.writer和上面的迭代器:

 import csv
 ...
 with ...:
 ...
    with open('outfile.csv', 'w') as output:
        writer = csv.writer(output)
        writer.writerow(header)
        for line in iterator:
            writer.writerow(re.split(r'\s+', line))

您可以将嵌套输出with和外部输入with组合到一个外部块中,以降低嵌套级别:

with open('file.dat') as file, open('outputfile.csv', 'w') as output:
    ....

要阅读pandas DataFrame,您只需将file对象传递给pandas.read_csv即可。由于文件流此时已超过标题,因此不会给您带来任何问题:

import pandas as pd
...
with ...:
    ...
    df = pd.read_csv(file, sep=r'\s'+, header=None, names=header)