将多个文件追加到一个文件中,跳过第一行并排序

时间:2015-03-02 10:29:10

标签: python bash sorting pandas awk

我有一个包含每小时值的月度文件的文件夹。 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
...

附加部分非常简单,但我确信有更好的方法,特别是考虑到我还需要做两件事:

  1. 跳过要追加的每个文件的标题。没关系第一个实例,我可以在之后粘贴一个。
  2. 根据第2列对生成的附加文件进行排序,以将工作站名称组合在一起,然后在第1列上按小时对每个工作站进行排序。
  3. 期望的结果:

    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库来处理时间序列。如果是这样,我猜一组或两个。

2 个答案:

答案 0 :(得分:3)

使用-s的GNU排序(稳定排序):

awk 'FNR > 1' *.csv | sort -sk 2,2 | sort -sk 3,3

此处awk 'FNR > 1'过滤不是文件 1 第一行的行,sort -sk m,n按字段mn稳定排序}。要按小时排序,还要按日期排序,请使用

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'])