迭代。 csv文件 - >写入两本词典

时间:2016-04-01 16:16:01

标签: csv python-3.x dictionary iteration

csv看起来像这样:

2016-04-01 02:17    16.7    51.9
2016-04-01 02:18    16.7    51.9
2016-04-01 02:19    16.6    52.0
2016-04-01 02:20    16.6    52.2
2016-04-01 02:21    16.7    52.2
2016-04-01 02:22    16.7    52.1
2016-04-01 02:23    16.6    52.2
2016-04-01 02:24    16.6    52.2
2016-04-01 02:25    16.6    52.2

文件每隔一分钟记录传感器的温度和湿度。每个度量都是cvs文件中的一行。

我想迭代这个文件并添加行,具体取决于字典的时间。 因此,一个字典应该包含从nownow - 24hours的所有行,而另一个字典应该包含从nownow - 1week的所有行。 Now是当前时间,脚本已启动。 我不确定在迭代时如何做到这一点(如果可能的话)。 这是我打开文件并定义TimeRow的方式:

for row in f_reader:
    stringRowDate = row[0]
    Date = datetime.datetime.strptime(stringRowDate,"%Y-%m-%d %H:%M")
    stringDateNow = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
    DateNow = datetime.datetime.strptime(stringDateNow,"%Y-%m-%d %H:%M")

我的代码打开了csv文件:

if Date >= DateNow:
    continue
elif Date >= (DateNow - timedelta(weeks=1)):
    data_Week = {row[0]:row[1:] for row in f_reader}
rownum +=1

data_Week是字典,现在可以保存文件中从now1 Week的所有行。

我是否可以通过使用相同的迭代将24hours中的每一行添加到另一个词典(data_24)?

1 个答案:

答案 0 :(得分:1)

您可以单独检查每一行,而不是将所有其余数据发送到一个字典:

week_ago = (DateNow - timedelta(weeks=1))
day_ago = (DateNow - timedelta(days=1))
data_Week = {}
data_24 = {}
#data_before = {}

for row in f_reader:
    stringRowDate = row[0]
    Date = datetime.datetime.strptime(stringRowDate,"%Y-%m-%d %H:%M")
    if Date >= day_ago:
        data_24[row[0]] = row[1:]
    elif Date >= week_ago:
        data_Week[row[0]] = row[1:]
    else:
        continue
        #data_before[row[0]] = row[1:]

虽然这意味着如果方便地对文件进行排序,会不必要地检查很多条件,在这种情况下,您可以跟踪当前split_time以指示何时切换dict和current_data将指出将日期纳入其中的一项决定:

#first is the value to signal to go to next group
data_sorter = iter([(week_ago,None), #None placeholder to not keep data from before week_ago
                    (day_ago,data_Week),
                    (None,data_24)]) #no split for last one, just take the rest of data until end of reader
split_time,current_data = next(data_sorter)
for row in f_reader:
    stringRowDate = row[0]
    Date = datetime.datetime.strptime(stringRowDate,"%Y-%m-%d %H:%M")
    if split_time is not None and (Date > split_time):
        split_time,current_data = next(data_sorter)
    if current_data is not None: #make sure there is no placeholder
        current_data[row[0]] = row[1:]

根据程序中的其他内容,使用生成器可能更方便,因此不需要占位符:

from operator import lt #used only for the default check_f
def split_by_time(reader,*split_times, check_f=lt):
    split_times = iter(split_times)
    split_time = next(split_times,None)
    current_data = {}
    for line in reader:
        row_time,*row_data = line
        if split_time is not None and check_f(split_time,row_time):
            yield current_data
            split_time = next(split_times,None)
            current_data = {}
        current_data[row_time] = row_data
    yield current_data


def check_limit(split_date, date_from_file):
    "convert the string date from file to a datetime object for comparison"
    return split_date < datetime.datetime.strptime(date_from_file,"%Y-%m-%d %H:%M")

times = list(split_by_time(f_reader,
                        week_ago,day_ago, 
                        check_f=check_limit))

print("from before a week ago:\n",times[0])
print("from a week ago to a day ago:\n",times[1])
print("since yesterday:\n",times[2])

但这可能超过你真正需要的,我真的很喜欢发电机。 :d