我有一个包含每小时值的月度文件的文件夹。 12个文件中的每一个都有一个行标题。对于每个月,每个文件的每个小时都有一行。见下文:
Hours stn stn_id sen_id Elevation Latitude Longitude cnt avg_hrly
2010-01-01 00:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-01-01 01:00:00 Alberni 108 217 26 49.24596024 -124.8041687 59 0.0
...
2010-01-31 22:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-01-31 23:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
...
2010-01-01 00:00:00 Arbutus 79 159 57 48.47133255 -123.30664062 60 0.0
2010-01-01 01:00:00 Arbutus 79 159 57 48.47133255 -123.30664062 60 0.0
...
问题是,3月份来自夏令时班次的每个文件中的前一个月有一个小时,如下所示:
Hours stn stn_id sen_id Elevation Latitude Longitude cnt avg_hrly
2010-05-31 23:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-06-01 00:00:00 Alberni 108 217 26 49.24596024 -124.8041687 56 0.0
...
附加部分非常简单,但我确信有更好的方法,特别是考虑到我还需要做两件事:
期望的结果:
2010-01-01 00:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-01-01 01:00:00 Alberni 108 217 26 49.24596024 -124.8041687 59 0.0
...
2010-01-31 22:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-01-31 23:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-02-01 00:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-02-01 01:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-02-01 02:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
...
2010-05-31 20:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.6
2010-05-31 21:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-05-31 22:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-05-31 23:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-06-01 00:00:00 Alberni 108 217 26 49.24596024 -124.8041687 56 0.0
2010-06-01 01:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-06-01 02:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-06-01 03:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 0.0
2010-06-01 04:00:00 Alberni 108 217 26 49.24596024 -124.8041687 60 10.4
我想知道这是否需要一些awk和shell结合使用管道?
这是一些伪伪代码,只是为了表达方法:
for * .csv中的文件;做awk NR> 1 {print} | sort -k2,1n | >> year_appended.csv;完成
也许这是一个使用Python更好地克服的挑战,也许是使用Pandas库来处理时间序列。如果是这样,我猜一组或两个。
答案 0 :(得分:3)
使用-s
的GNU排序(稳定排序):
awk 'FNR > 1' *.csv | sort -sk 2,2 | sort -sk 3,3
此处awk 'FNR > 1'
过滤不是文件 1 第一行的行,sort -sk m,n
按字段m
到n
稳定排序}。要按小时排序,还要按日期排序,请使用
awk 'FNR > 1' *.csv | sort -sk 1,2 | sort -sk 3,3
请注意,这取决于日期和时间格式。幸运的是,日期和时间戳的词典比较与给定的表示一起工作,因此不需要更复杂的解析。
1 没有必要采取明确的{ print }
行动;当条件为真时执行默认操作(打印)。
附录:如果你有GNU awk并且文件中的字段是严格标签分隔的,你也可以使用
gawk -F '\t' 'FNR > 1 { data[$2,$1] = $0 } END { PROCINFO["sorted_in"] = "@ind_str_asc"; for(d in data) print data[d] }' *.csv
此处-F '\t'
告诉gawk将行拆分为选项卡中的字段,代码的工作方式如下:
FNR > 1 { # for all lines that are not the
# first of a file:
data[$2,$1] = $0 # remember them by fields 2 and 1
}
END {
PROCINFO["sorted_in"] = "@ind_str_asc" # GNU-specific: Require sorted
# traversal of arrays.
for(d in data) { # Then print the lines in that
print data[d] # sorted order.
}
}
答案 1 :(得分:3)
一些伪代码,你不需要跳过这里的行,因为concatenation 将为你排列列,也可以更快地制作一个dfs列表然后连接它们一起而不是一次附加一个df:
# assuming you have a list of the files you want to load, probably via glob
df_list=[]
for file in file_list:
df_list.apend(pd.read_csv(file, parse_dates=['Hours']))
merged = pd.concat(df_list)
# sort the data
merged = merged.sort(['stn', 'Hours'])