【问题标题】:Overwrite a specific column in a csv file using Python csv module使用 Python csv 模块覆盖 csv 文件中的特定列
【发布时间】:2013-05-20 10:53:15
【问题描述】:

我正在使用 Python csv 模块读取一个 csv 文件,其中每一行都像:

2013-04-16 7:11:01,186744,3,2,2,1.89E-03

然后我将 row[0] 转换为 unix 时间,但我想用我刚刚为 csv 文件的每一行找到的 unix 时间替换 datetime

import pymongo
import datetime
import re
import csv
import calendar

X = []
OBD = []
Y = []

csv_in = open('FakeAPData.csv', 'rb')


for row in reader:
    date = datetime.datetime.strptime(row[0], '%Y-%m-%d %H:%M:%S')
    datet = unicode(datetime.datetime.strptime(row[0], '%Y-%m-%d %H:%M:%S'))
    datett = tuple(int(v) for v in re.findall("[0-9]+", datet))
    y = calendar.timegm(datett)
    Y.append(y)

所以我用 unixtime 值创建了列表 Y,但是我该如何进行替换才能得到这样的输出:

1366097085,186744,3,2,2,1.89E-03

【问题讨论】:

    标签: python csv overwrite


    【解决方案1】:

    每个row 只是一个list。您可以就地修改它,或者使用您要替换的值创建一个新列表:

    row[0] = y # or row = [y] + row[1:], or ...
    

    如果要将其写回文件,则需要为此使用csv.writer。例如:

    os.rename('FakeAPData.csv', 'FakeAPData.csv.bak')
    
    csv_in = open('FakeAPData.csv.bak', 'rb')
    csv_out = open('FakeAPData.csv', 'wb')
    
    writer = csv.writer(csv_out)
    
    for row in csv.reader(csv_in):
        date = datetime.datetime.strptime(row[0], '%Y-%m-%d %H:%M:%S')
        datet = unicode(datetime.datetime.strptime(row[0], '%Y-%m-%d %H:%M:%S'))
        datett = tuple(int(v) for v in re.findall("[0-9]+", datet))
        y = calendar.timegm(datett)
        row[0] = y
        writer.writerow(row)
    

    当然,您还需要close 您的文件,并清理所有重复和未使用的代码。当我们这样做时,我会将日期转换代码分解为一个函数。并使用让事情变得简单的函数,而不是让事情变得困难和脆弱的函数。

    所以:

    def transform_date(date):
        return calendar.gmtime(datetime.strptime(date, '%Y-%m-%d %H:%M:%S').timetuple())
    
    def transform_row(row):
        return [transform_date(row[0])] + row[1:]
    
    name = 'FakeAPData.csv'
    bakname = name + '.bak'
    os.rename(name, bakname)
    with open(bakname, 'rb') as in csv_in, open(name, 'wb') as csv_out:
        writer = csv.writer(csv_out)
        writer.writerows(transform_row(row) for row in csv.reader(csv_in))
    

    【讨论】:

    • 将 ISO 格式的日期时间转换为时间戳的方法真的太可怕了。如果可以避免的话,不要让它长期存在。
    【解决方案2】:

    首先,有更好的方法可以将文本日期时间格式转换为 UNIX 时间戳。直接使用time module 可以将您的代码简化为:

    import time
    import calendar
    
    timestamp = calendar.gmtime(time.strptime(row[0], '%Y-%m-%d %H:%M:%S'))
    

    但即使您创建的 datetime 对象也有 .timetuple().utctimetuple() 方法,它们在生成 time_struct 元组时比将 datetime 对象的字符串格式解析回元组更可靠整数。您也可以在row[0]直接执行此操作,因为str(datetime.now()) 的输出与您开始使用的格式相同。

    接下来,写出一个新文件并在完成后用它替换旧文件:

    import csv
    import time
    import calendar
    import os
    
    with open('FakeAPData.csv', 'rb') as infile, open('FakeAPData.csv.new', 'wb') as outfile:
        writer = csv.writer(outfile)
        for row in csv.reader(infile):
            timestamp = calendar.gmtime(time.strptime(row[0], '%Y-%m-%d %H:%M:%S'))
            writer.writerow([timestamp] + row[1:])
    
    os.rename('FakeAPData.csv.new', 'FakeAPData.csv')
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-06
      • 1970-01-01
      • 1970-01-01
      • 2013-12-28
      • 1970-01-01
      相关资源
      最近更新 更多