为.csv fi选择循环内的特定日期

2024-09-27 00:15:52 发布

您现在位置:Python中文网/ 问答频道 /正文

Name,USAF,NCDC,Date,HrMn,I,Type,Dir,Q,I,Spd,Q

OXNARD,723927,93110,19590101,0000,4,SAO,270,1,N,3.1,1, 
OXNARD,723927,93110,19590101,0100,4,SAO,338,1,N,1.0,1, 
OXNARD,723927,93110,19590101,0200,4,SAO,068,1,N,1.0,1, 
OXNARD,723927,93110,19590101,0300,4,SAO,068,1,N,2.1,1, 
OXNARD,723927,93110,19590101,0400,4,SAO,315,1,N,1.0,1, 
OXNARD,723927,93110,19590101,0500,4,SAO,999,1,C,0.0,1, 
....

OXNARD,723927,93110,19590102,0000,4,SAO,225,1,N,2.1,1,
OXNARD,723927,93110,19590102,0100,4,SAO,248,1,N,2.1,1,
OXNARD,723927,93110,19590102,0200,4,SAO,999,1,C,0.0,1,
OXNARD,723927,93110,19590102,0300,4,SAO,068,1,N,2.1,1,

这是一个csv文件的片段,在每一行中存储每小时的风速(Spd)。我想做的是在csv文件中选择每天的所有每小时风,并将它们存储到一个临时的每日列表中,存储当天的所有小时值(如果没有丢失值,则为24)。然后,我将输出当前一天的列表,为第二天创建新的空列表,查找第二天的每小时速度,输出该每日列表,以此类推,直到文件结束。在

我正在努力寻找一个好方法来做这件事。我的一个想法是在第一行读,确定日期(YYYY-MM-DD),然后读I+1行,看看这个日期是否与日期I匹配。如果它们匹配,那么我们就在同一天。如果他们没有,那么我们就进入第二天。但我甚至不知道该如何读取文件的下一行。。。在

有什么建议来执行这个方法或者一个全新的(更好的?!)方法是最受欢迎的。提前谢谢你!在

^{pr2}$

Tags: 文件csv方法name列表datetypedir
3条回答

我知道这个问题是多年前的问题,但我只想指出,一个小型bash脚本可以灵活地执行这个任务。我把你的例子复制到一个叫做数据.txt这是剧本:

#!/bin/bash
date=19590101
date_end=19590102
while [[ $date -le $date_end ]] ; do
  grep ",${date}," data.txt > file_${date}.txt
  date=`date +%Y%m%d -d ${date}+1day` # NOTE: MAC-OSX date differs
done

注意,这在MAC上不起作用,因为某些原因date命令的实现是不同的。如果文件中缺少日期,grep命令将生成一个空文件-此链接显示了避免这种情况的方法: how to stop grep creating empty file if no results

您可以利用数据文件的有序性并使用csv.dictreader。然后你可以建立一个按日期组织的风速字典,你可以随意处理。请注意,csv读取器返回字符串,因此您可能希望在组装列表时根据需要转换为其他类型。在

import csv
from collections import defaultdict
bydate = defaultdict(list)
rdr = csv.DictReader(open('winds.csv','rt'))
for k in rdr:
    bydate[k['Date']].append(float(k['Spd']))

print(bydate)
defaultdict(<type 'list'>, {'19590101': [3.1000000000000001, 1.0, 1.0, 2.1000000000000001, 1.0, 0.0], '19590102': [2.1000000000000001, 2.1000000000000001, 0.0, 2.1000000000000001]})

显然,您可以更改元组的append调用的参数,例如append((float(k['Spd']), datetime.datetime.strptime(k['Date']+k['HrMn'],'%Y%m%D%H%M)),这样您也可以收集时间。在

如果文件有多余的空格,可以使用skipinitialspace参数:rdr = csv.DictReader(open('winds.csv','rt'), fieldnames=ff, skipinitialspace=True)。如果仍然不起作用,可以预处理标题行:

^{pr2}$

bydate的访问方式与普通词典类似。要访问某一天的数据,请执行bydate['19590101']。要获取已处理的日期列表,可以执行bydate.keys()。在

如果要在读取文件时将它们转换为Python日期时间对象,可以导入datetime,然后将赋值行替换为bydate[datetime.datetime.strptime(k['Date'], '%Y%m%d')].append(k['Spd'])。在

可能是这样的。在

def dump(buf, date):
    """dumps buffered line into file 'spdYYYYMMDD.csv'"""
    if len(buf) == 0: return
    with open('spd%s.csv' % date, 'w') as f:
        for line in buf:
             f.write(line)

obs_in  = open(csv_file).readlines()
# buf stores one day record
buf = []
# date0 is meant for time stamp for the buffer
date0 = None
for i in range(1,len(obs_in)):        
    # Skip over the header lines 
    if not str(obs_in[i]).startswith("Identification") and \
        not str(obs_in[i]).startswith("Name"):
        name,usaf,ncdc,date,hrmn,ii,type,dir,q,i2,spd,q2,blank = \
            obs_in[i].split(',')
        current_dt  = datetime.date(int(date[0:4]),int(date[4:6]),int(date[6:8]))
        current_spd = spd 
        # see if the time stamp of current record is different.  if it is different
        # dump the buffer, and also set the time stamp of buffer
        if date != date0:
            dump(buf, date0)
            buf = []
            date0 = date
        # you change this.  i am simply writing entire line
        buf.append(obs_in[i])

# when you get out the buffer should be filled with the last day's record.  
# so flush that too.
dump(buf, date0)

我还发现我必须使用ii代替i作为数据的字段“I”,就像您使用i作为循环计数器一样。在

相关问题 更多 >

    热门问题