重塑表以创建由前缀

时间:2015-11-05 22:01:23

标签: python r excel reshape2 data-manipulation

我有一张类似于以下内容的表格:

name,time_in,time_out
jim,1/1/2000 08:24,1/1/2000 15:24
jim,1/2/2000 08:13,1/2/2000 16:24
jim,1/3/2000 08:14,1/3/2000 15:25
jim,1/4/2000 08:33,1/4/2000 16:23
linda,1/1/2000 08:24,1/1/2000 15:24
mark,1/2/2000 08:13,1/2/2000 16:24
mark,1/3/2000 08:14,1/3/2000 15:25
mark,1/4/2000 08:33,1/4/2000 16:23

忽略实际时间,点是天不排队。我所看到的重新塑造的大部分内容都具有良好和正方形,我的数据最终可能会被重新整形。是否有一种简单的方法(寻找R解决方案,但对Excel或其他任何东西开放)来创建类似于以下内容的表聚合:

jim,1/1/2000 08:24,1/1/2000 15:24,1/2/2000 08:13,1/2/2000 16:24,1/3/2000 08:14,1/3/2000 15:25,1/4/2000 08:33,1/4/2000 16:23
linda,1/1/2000 08:24,1/1/2000 15:24
mark,1/2/2000 08:13,1/2/2000 16:24,1/3/2000 08:14,1/3/2000 15:25,1/4/2000 08:33,1/4/2000 16:23

每个人聚合到一行(此时不知道如何处理标题,请提供建议。)

2 个答案:

答案 0 :(得分:1)

假设所有要在同一名称下聚合的行都是连续的,这个Python脚本

from itertools import groupby

with open('infile.txt') as in_f, open('outfile.txt', 'w') as out_f:
    next(in_f)  # skip header
    aggr = groupby(in_f, lambda line: line.partition(',')[0])
    for k, lines in aggr:
        slines = (l.lstrip(k+',').rstrip() for l in lines)
        out_line = k+','+','.join(slines)+'\n'
        out_f.write(out_line)

诀窍。

例如,输入文件为

name,time_in,time_out
jim,1/1/2000 08:24,1/1/2000 15:24
jim,1/2/2000 08:13,1/2/2000 16:24
jim,1/3/2000 08:14,1/3/2000 15:25
jim,1/4/2000 08:33,1/4/2000 16:23
linda,1/1/2000 08:24,1/1/2000 15:24
mark,1/2/2000 08:13,1/2/2000 16:24
mark,1/3/2000 08:14,1/3/2000 15:25
mark,1/4/2000 08:33,1/4/2000 16:23

它会生成

的输出文件
jim,1/1/2000 08:24,1/1/2000 15:24,1/2/2000 08:13,1/2/2000 16:24,1/3/2000 08:14,1/3/2000 15:25,1/4/2000 08:33,1/4/2000 16:23
linda,1/1/2000 08:24,1/1/2000 15:24
mark,1/2/2000 08:13,1/2/2000 16:24,1/3/2000 08:14,1/3/2000 15:25,1/4/2000 08:33,1/4/2000 16:23

它利用itertools.groupby

的力量

基本上,只要前缀(即名称)不变,它就会对行进行分组。当它移动时,在新找到的前缀上创建另一个组。 然后它只是将每个组的元素连接在一行上,用','

分隔

注意:如果您希望标题出现在输出文件中,请更改行

    next(in_f)  # skip header

    out_f.write(next(in_f))  # write and skip header

答案 1 :(得分:1)

考虑这个基本的R解决方案,它使用不同名称的运行计数和重新计算长到计数:

# RECREATING DATA FRAME
df <- data.frame(name = c("Jim", "Jim", "Jim", "Jim", "linda", "mark", "mark", "mark"),
       time_in = c("1/1/2000 8:24", "1/2/2000 08:13", "1/3/2000 08:14", "1/4/2000 08:33",
                   "1/1/2000 08:24", "1/2/2000 08:13", "1/3/2000 08:14", "1/4/2000 08:33"),
       time_out = c("1/1/2000 15:24", "1/2/2000 16:24", "1/3/2000 15:25", "1/4/2000 16:23",
                    "1/1/2000 15:24", "1/2/2000 16:24", "1/4/2000 15:25", "1/4/2000 16:23"))

# COUNTING BY GROUPED NAMES
df$numcount <- sapply(1:nrow(df),
                      function(i) sum(df[1:i, c("name")] == df$name[i]))

# RESHAPING LONG TO WIDE
reshapedf <- reshape(df, v.names = c("time_in", "time_out"), 
                           timevar=c("numcount"), idvar = c("name"), 
                           direction = "wide")

row.names(reshapedf) <- NULL

reshapedf

<强>输出

   name      time_in.1     time_out.1      time_in.2     time_out.2      time_in.3     time_out.3      time_in.4     time_out.4
1   Jim  1/1/2000 8:24 1/1/2000 15:24 1/2/2000 08:13 1/2/2000 16:24 1/3/2000 08:14 1/3/2000 15:25 1/4/2000 08:33 1/4/2000 16:23
2 linda 1/1/2000 08:24 1/1/2000 15:24           <NA>           <NA>           <NA>           <NA>           <NA>           <NA>
3  mark 1/2/2000 08:13 1/2/2000 16:24 1/3/2000 08:14 1/4/2000 15:25 1/4/2000 08:33 1/4/2000 16:23           <NA>           <NA>