将多个文件附加到一个文件中,跳过第一行并排序
append multiple files into one, skip the first row and sort
我有一个文件夹,其中包含每小时值的月度文件。 12 个文件中的每一个都有一行 header。每个文件都有一行代表那个月的每个站的每小时。见下文:
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
...
附加部分非常简单,但我确信有更好的方法,尤其是考虑到我还需要做两件事:
- 跳过每个附加文件的 header。没关系第一个实例,我可以在顶部粘贴一个。
- 根据第 2 列对生成的附加文件进行排序以获取站名,然后在第 1 列按小时对每个站进行排序。
期望的结果:
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 file in *.csv; do awk NR>1 {print} | sort -k2,1n | >>
year_appended.csv ; done
也许这是一个使用 Python 更好地克服的挑战,也许使用 Pandas 库来处理时间序列。如果是这样,我猜是一组语句,或两个。
使用 GNU 排序 -s
(稳定排序):
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[,] = [=12=] } 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[,] = [=13=] # 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.
}
}
一些伪代码,你不需要跳过这里的行,因为 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'])
我有一个文件夹,其中包含每小时值的月度文件。 12 个文件中的每一个都有一行 header。每个文件都有一行代表那个月的每个站的每小时。见下文:
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
...
附加部分非常简单,但我确信有更好的方法,尤其是考虑到我还需要做两件事:
- 跳过每个附加文件的 header。没关系第一个实例,我可以在顶部粘贴一个。
- 根据第 2 列对生成的附加文件进行排序以获取站名,然后在第 1 列按小时对每个站进行排序。
期望的结果:
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 file in *.csv; do awk NR>1 {print} | sort -k2,1n | >> year_appended.csv ; done
也许这是一个使用 Python 更好地克服的挑战,也许使用 Pandas 库来处理时间序列。如果是这样,我猜是一组语句,或两个。
使用 GNU 排序 -s
(稳定排序):
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[,] = [=12=] } 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[,] = [=13=] # 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.
}
}
一些伪代码,你不需要跳过这里的行,因为 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'])