在Python中每小时生成多个CSV文件

1 投票
4 回答
2482 浏览
提问于 2025-04-18 14:43

我有一个叫做 HourlyCsvGeneration.py 的 Python 模块。我有一些数据是每小时生成一次,这些数据保存在 sample.txt 文件里。下面是 sample.txt 中数据的一个示例:

2014-07-24 15:00:00,1,1,1,1,1001
2014-07-24 15:01:00,1,1,1,1,1001
2014-07-24 15:02:00,1,1,1,1,1001
2014-07-24 15:15:00,1,1,1,1,1001
2014-07-24 15:16:00,1,1,1,1,1001
2014-07-24 15:17:00,1,1,1,1,1001
2014-07-24 15:30:00,1,1,1,1,1001
2014-07-24 15:31:00,1,1,1,1,1001
2014-07-24 15:32:00,1,1,1,1,1001
2014-07-24 15:45:00,1,1,1,1,1001
2014-07-24 15:46:00,1,1,1,1,1001
2014-07-24 15:47:00,1,1,1,1,1001

从上面可以看到,有四个时间段:00-15、15-30、30-45 和 45-59,接下来就是下一个小时,依此类推。我正在写代码,读取这个文本文件中的数据,并为一天中的每个小时生成四个 CSV 文件。根据上面的数据,这四个 CSV 文件的命名规则应该是这样的:2014-07-24 15:00.csv,里面包含15:00到15:15之间的数据;2014-07-24 15:15.csv,里面包含15:15到15:30之间的数据,依此类推,每个小时都这样。这个 Python 代码需要处理所有这些事情。

这是我目前的代码片段:

import csv
def connection():
    fo = open("sample.txt", "r")
    data = fo.readlines()
    header = ['tech', 'band', 'region', 'market', 'code']
    for line in data:
            line = line.strip("\n")
            line = line.split(",")
            time = line[0]
            lines = [x for x in time.split(':') if x]
            i = len(lines)
            if i == 0:
                    continue
            else:
                    hour, minute, sec = lines[0], lines[1], lines[2]
                    minute = int(minute)
                    if minute >= 0 and minute < 15:
                            print hour, minute
                            print line[1:]
                    elif minute >= 15 and minute < 30:
                            print hour, minute
                            print line[1:]
                    elif minute >= 30 and minute < 45:
                            print hour, minute
                            print line[1:]
                    elif minute >=45 and minute < 59:
                            print hour, minute
                            print line[1:]
connection()

[1:] 可以给出每个时间段的正确数据,但我在生成 CSV 文件和写入数据时遇到了困难。所以我想把 [1:] 的内容写入对应时间段的 CSV 文件中,并按照上面描述的命名规则来命名。

期望的输出是:

2014-07-24 15:00.csv must contain
1,1,1,1,1001
1,1,1,1,1001
1,1,1,1,1001

2014-07-24 15:15.csv must contain
1,1,1,1,1001
1,1,1,1,1001
1,1,1,1,1001

这样对于 15:30.csv 和 15:45.csv 也是一样。请记住,这只是一个小数据块。实际的数据是每小时都有的。这意味着每个小时生成四个 CSV 文件,也就是一天要生成 24*4 个文件。那么我该如何让我的代码更健壮和高效呢?

有什么帮助吗?谢谢!

4 个回答

0

我建议你使用pandas来处理这个问题。它可以帮你处理很多繁琐的工作。

import pandas as pd

df = pd.read_table('DummyText.txt',sep=',',index_col=0,parse_dates=True,header=None)
fname = (str(pd.datetime(2014,7,24,15,0))+'.csv').replace(':','-')
df[pd.datetime(2014,7,24,15,0):pd.datetime(2014,7,24,15,15)].to_csv(fname,header=None)

我把文件名中的:去掉了,因为它似乎不喜欢这个符号。你只需要设置一些循环来遍历日期和时间就可以了。

0

这里有一些可能对你有帮助的方法

import csv
from datetime import datetime

def get_higher_minute(minute_of_day):
    return (((minute_of_day/ 15) + 1 ) % 4) * 15

def connection():
    import csv
    with open('some.csv', 'rb') as f:
        reader = csv.reader(f)
        for row in reader:
            dateObject = datetime.strptime(row[0], '%Y-%m-%d %H:%M:%S')
            minute_of_day = dateObject.minute
            higher_minute = get_higher_minute(minute_of_day)
            newdate = dateObject.replace(minute = higher_minute)
            file_name_of_new_csv = "%s.csv" % dateObject.strftime("%Y-%m-%d %H:%M")
            new_csv_writer = csv.writer(file_name_of_new_csv, delimiter=',', quotechar='"', quoting=csv.QUOTE_ALL)
            new_csv_writer.writerow(row[0:])
            new_csv_writer.close()            

def main():
    connection()

if __name__=="__main__":
    main()

希望这些能帮到你

抱歉,我忘记关闭 new_csv_writer 了。

0

你的问题并不简单,因为如果你试图一次性打开所有的输出文件,你会用完文件描述符,导致程序崩溃。所以你应该做的是以追加模式打开一个文件,写入一行内容,然后关闭这个文件。这种操作效率不是特别高,所以现在不需要太担心效率的问题。

outfile = open("2014-07-24 15:00.csv","a")
outfile.write("csv, line, data\n")
outfile.close()
0

看起来这个问题可以用 itertools.groupby 来解决,前提是时间戳的值是严格递增的:

from datetime import datetime as DateTime
from itertools import imap, groupby
from operator import itemgetter


get_first = itemgetter(0)
get_second = itemgetter(1)


def process_line(line):
    timestamp_string, _, values = line.partition(',')
    timestamp = DateTime.strptime(timestamp_string, '%Y-%m-%d %H:%M:%S')
    return (
        timestamp.replace(minute=timestamp.minute // 15 * 15, second=0),
        values
    )


def main():
    with open('sample.txt', 'r') as lines:
        for date, group in groupby(imap(process_line, lines), get_first):
            with open('{0:%Y-%m-%d %H_%M}.csv'.format(date), 'w') as out_file:
                out_file.writelines(imap(get_second, group))


if __name__ == '__main__':
    main()

撰写回答