【问题标题】:adding missing seconds in a data frame in R or Python在 R 或 Python 的数据框中添加丢失的秒数
【发布时间】:2017-09-15 01:57:01
【问题描述】:

假设我有以下格式的数据:

Time  Value
0.11  15
0.23  35
0.87  78
1.01  14
1.13  98
1.59  11
1.78  4
5.33  6
5.78  32
5.81  39

这里的时间以秒为单位。假设帧速率为每秒 3 或 4。换句话说,每秒可以有 3 或 4 行。是给定的数据集是不规则的。

有时,像这里这样的秒数会有跳跃(从 1.78 到 5.33 - 缺少 2、3 和 4 秒)。

现在每丢失一秒,我想添加 3 行以获得如下的最终数据:

Time  Value
0.11  15
0.23  35
0.87  78
1.01  14
1.13  98
1.59  11
1.78  4
2.01  NA
2.13  NA
2.59  NA
3.01  NA
3.13  NA
3.59  NA
4.01  NA
4.13  NA
4.59  NA
5.33  6
5.78  32
5.81  39

我将如何在 R 或 python 中使用其他一些编程语言来做到这一点?

假设 .01、.13、.59(在最终输出中)是什么并不重要……可以是 .01、.02、.03。只要有0、1、2、3、4、5秒而不是0、1、5秒

更新:@r2evans 解决方案在有一个时间间隔时效果很好。我将如何处理多个时间间隔,如下所示:

Time  Value
0.11  15
0.23  35
0.87  78
1.01  14
1.13  98
1.59  11
1.78  4
5.33  6
5.78  32
5.81  39
6.01  14
6.13  98
6.59  11
7.78  4
7.33  6
7.81  39
12.78  4
12.33  6
12.81  39

【问题讨论】:

  • “时间”中的模式尚不清楚。如果我们看相邻元素之间的差异,那是不一样的
  • 数据实际上是这样的。我们唯一知道的是每秒有 3 个或 4 个数据点
  • 您的预期结果似乎完全随机 - 为什么是 .78、.13 和 .59?
  • 假设 .78、.13、.59 是什么无关紧要......它可以是 .01、.02、.03。只要有0、1、2、3、4、5秒而不是0、1、5
  • 那么如果可以有“每秒 3 行或 4 行”,我们如何知道是添加 3 行还是 4 行缺失?我认为我们都在努力了解如何从给定的数据到期望的结果。

标签: python r dataframe dataset time-series


【解决方案1】:
txt <- "Time  Value
0.11  15
0.23  35
0.87  78
1.01  14
1.13  98
1.59  11
1.78  4
5.33  6
5.78  32
5.81  39"
dat <- read.table(text = txt, header = TRUE)

一些常量:

# largest "gap" possible, above which the gap will be "filled"
maxsplit <- 1 # sec
# when a gap is found, ensure times with this much gap are inserted
time_interval <- 1/3 # sec

找出所有这些缝隙的位置:

splits <- cumsum(diff(dat$Time) < maxsplit) # updated
split_inds <- which(duplicated(splits))     # updated

split_inds 是一个索引向量,之后有 1 秒或更长的间隔。对于这些差距中的每一个,我们每隔time_interval 秒就sequence。它可能并不总是等间距,但它会提供覆盖范围。

newtimes <- mapply(seq,
                   dat$Time[split_inds],
                   dat$Time[split_inds + 1],
                   MoreArgs = list(by = time_interval),
                   SIMPLIFY = FALSE)          # updated
newtimes <- unlist(lapply(newtimes, `[`, -1)) # updated
newtimes
# [1] 2.113333 2.446667 2.780000 3.113333 3.446667 3.780000
# [7] 4.113333 4.446667 4.780000 5.113333

从那里,我们需要删除第一行,因为它在原始数据中逐字存在。 (请注意,如果间隙是time_interval 的完美倍数,最后一行也可能是重复的......可以使用其他过滤器,也许寻找duplicated(dat$Time),也许硬编码检查近似相等。 编辑:我的这个答案的第一个版本也总是删除最后一行,这可能会导致2*time_interval 的差距。)

newdat <- rbind(dat, 
                data.frame(Time = newtimes, Value = NA)) # updated

我假设需要通过$Time 订购...

newdat <- newdat[order(newdat$Time),]

结果数据。

newdat
#        Time Value
# 1  0.110000    15
# 2  0.230000    35
# 3  0.870000    78
# 4  1.010000    14
# 5  1.130000    98
# 6  1.590000    11
# 7  1.780000     4
# 11 2.113333    NA
# 12 2.446667    NA
# 13 2.780000    NA
# 14 3.113333    NA
# 15 3.446667    NA
# 16 3.780000    NA
# 17 4.113333    NA
# 18 4.446667    NA
# 19 4.780000    NA
# 20 5.113333    NA
# 8  5.330000     6
# 9  5.780000    32
# 10 5.810000    39

更新

代码中有一个错误,已在上面修复(并已注释)。不过,有一个假设是,$Time 是有序的;如果这个不放心,应该在上面的代码之前做:

dat <- dat[ order(dat$Time), ]

【讨论】:

  • 感谢您的回答。如果数据集中只有一个间隙,则此方法有效。我将如何处理多个空白?我使用具有多个间隙的示例数据集更新了原始问题。您当前的解决方案会出现此错误Error in seq.default(dots[[1L]][[3L]], dots[[2L]][[3L]], by = 0.333333333333333) : wrong sign in 'by' argument
  • 好的。我补充说,但是,还有一个存在多个差距的问题:Error in match.names(clabs, names(xi)) : names do not match previous names PS:非常感谢您的帮助
  • 当我使用您的新数据和上面的代码时(顺便说一句,rbind 调用中的另一个次要且不相关的更改),它可以正常工作而不会出现错误或警告。但是,我可以通过使用不同的列名来重现该错误;确保正确拼写 TimeValue(区分大小写)或将 all 对它们的引用更改为实际的列标题。
  • 谢谢!完美运行
【解决方案2】:

我相信有人会想出一个更优雅的解决方案,但这应该可行:

Time  <- c(0.11, 0.23, 0.87, 1.01, 1.13, 1.59, 1.78, 5.33, 5.78, 5.81)
Value <- c(15, 35, 78, 14, 98, 11, 4, 6, 32, 39)

v1 <- data.frame(Time, Value, rounded=floor(Time))
v <- v1

for (i in min(v1$rounded):max(v1$rounded)) {

    while (length(which(v1$rounded == i)) < 3) {

        nextTimeVal <- max(v1$Time[v1$rounded == i])
        if (!is.finite(nextTimeVal)) {
            nextTimeVal <- i + 0.001
        } else {
            nextTimeVal <- nextTimeVal + 0.001
        }

        v1 <- rbind(v1, c(nextTimeVal, NA, i))
    }
    cat(i, '\n')

}

v1 <- v1[order(v1$Time), ]

print(v)
print(v1)

【讨论】:

  • 是的,r2evans 打败了我。
猜你喜欢
  • 2011-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
相关资源
最近更新 更多