使用Python以文本格式读取文件并以数据格式将其写入CSV文件

时间:2015-06-04 05:05:49

标签: csv python-3.x

我正在尝试使用CSV格式的数据转换一个包含文本文件的文件夹,以便执行一些进一步的数据分析。文本文件的第一行包含由;分隔的字符串,第二行包含相应的数据。我无法以文本格式读取文件并将其写入数据格式的CSV文件中。我的代码看起来像这样但是给了我关于无法将字符串转换为缓冲区接口的错误。

import os
import sys
import csv

# Open a file
full_path = "C:\\Documents and Settings\\30695\\My Documents\\Database"
dirs = os.listdir( full_path )

# This would print all the files and directories
for file in dirs:
   path = full_path+'\\'+file
   print (file)
   filename = (os.path.splitext(file)[0])
   print (filename)
   txt_file = filename
   csv_file = filename

   in_txt = csv.reader(open(full_path+'\\'+txt_file+'.txt', "rt"), delimiter = ';')
   out_csv = csv.writer(open(full_path+'\\'+csv_file+'.csv', 'wb'))
   out_csv.writerows(in_txt)

我不确定即使所有这些都是对或错,因为我希望CSV文件也用分隔符;分隔,并且所有数字都应以数据格式提供以进行计算。

输入文件看起来有点像这样:

"createTime";"Grid CosPhi";"Grid Current";"Grid Frequency";"Grid kW";"Grid VAr";"Grid Voltage";"Pitch angle 1";"Pitch angle 2";"Pitch angle 3";"Rotor RPM";"Temp.  5    214";"Temp.  6    217";"Temp.  9    227";"Winddirection";"Windspeed"
9/21/14 11:30:01 PM;N/A;N/A;49.963;211688.734;N/A;N/A;-1.06;-1.039;-1.119;19.379;47.167;36;64;N/A;6.319
9/21/14 11:40:01 PM;N/A;N/A;50.002;170096.297;N/A;N/A;-1.003;-0.96;-1.058;19.446;47.182;36.084;63.772;N/A;5.628
9/21/14 11:50:01 PM;N/A;N/A;50.021;175038.734;N/A;N/A;-0.976;-0.961;-1.082;18.805;47;36.223;63.153;N/A;5.577
9/22/14 12:00:01 AM;N/A;N/A;49.964;229942.016;N/A;N/A;-1.047;-1.018;-1.066;18.957;47.125;36.293;63.766;N/A;6.431
9/22/14 12:10:01 AM;N/A;N/A;49.908;200873.844;N/A;N/A;-0.997;-0.985;-1.06;19.229;47.028;36.334;63.962;N/A;6.076
9/22/14 12:20:01 AM;N/A;N/A;49.934;234467.609;N/A;N/A;-1.028;-0.986;-1.001;18.995;47.056;36.401;63.732;N/A;6.067

2 个答案:

答案 0 :(得分:1)

如果您在Python 2.6或2.7下运行此代码,一切都很好。 Python 3.X对于如何打开文件以及如何写入文件更加挑剔。

用于读写的2.7 documentation works with binary mode opened个文件。在3.4中,文件的打开已经变得清晰,然后您应该打开reading or writing with r, resp. w(省略t或“b'”,以便解释器可以执行所需的操作:

in_txt = csv.reader(open(os.path.join(full_path, txt_file+'.txt'), "r"), delimiter = ';')
out_csv = csv.writer(open(os.path.join(full_path, csv_file+'.csv'), 'w'))

我会稍微更新整个代码:

import os
import sys
import csv

# Open a file
full_path = r"C:\Documents and Settings\30695\My Documents\Database"
dirs = os.listdir( full_path )

# This would print all the files and directories
for file in dirs:
    path = os.path.join(full_path, file)
    print (file)
    filename, ext = os.path.splitext(file)
    if ext != '.txt':
        continue
    print (filename)
    txt_file = filename
    csv_file = filename

    in_txt = csv.reader(open(os.path.join(full_path, txt_file+'.txt'), "r"), delimiter = ';')
    out_csv = csv.writer(open(os.path.join(full_path, csv_file+'.csv'), 'w'))
    out_csv.writerows(in_txt)

使用raw原始字符串作为路径,这样你就不必逃避反斜杠;使用os.path.join()替换字符串的连接以创建完整的文件名(我不得不因为我在Linux上测试过这个);并跳过非.txt个文件,因为一旦您在.csv目录中创建了fullpath文件,这些文件也将由listdir()拨出。

我在ruamel.yamlyaml实用程序中使用CSV文件生成YAML文件的方法是迭代 输入中的行并使用process_line转换它们:

import dateutil.parser # https://pypi.python.org/pypi/python-dateutil

def process_line(line):
    """convert lines, trying, int, float, date"""
    ret_val = []
    for elem in line:
        try:
            res = int(elem)
            ret_val.append(res)
            continue
        except ValueError:
            pass
        try:
            res = float(elem)
            ret_val.append(res)
            continue
        except ValueError:
            pass
        try:
            res = dateutil.parser.parse(elem)
            ret_val.append(res)
            continue
        except TypeError:
            pass
        ret_val.append(elem)
    return ret_val

使用你需要用以下内容替换out_csv.writerows(in_txt)

for line in in_txt:
    out_csv.writerow(convert_line(line))

答案 1 :(得分:0)

我认为问题在于读者正在以字符串格式阅读,但作者正在尝试以二进制格式编写。如果您将代码更改为此会发生什么?:

out_csv = csv.writer(open(full_path+'\\'+csv_file+'.csv', 'wt'))