如何快速转换大数据帧中的不同时间格式?

2024-04-05

我想计算不同时间维度的长度,但在处理数据框列中两种略有不同的时间格式时遇到问题。

原始数据框列大约有一百万行,两种格式(如示例代码所示)混合在一起。

示例代码:

time <- c("2018-07-29T15:02:05Z", "2018-07-29T14:46:57Z",
         "2018-10-04T12:13:41.333Z", "2018-10-04T12:13:45.479Z")

length <- c(15.8, 132.1, 12.5, 33.2)

df <- data.frame(time, length)

df$time <- format(as.POSIXlt(strptime(df$time,"%Y-%m-%dT%H:%M:%SZ", tz="")))
df

格式"2018-10-04T12:13:41.333Z" and "2018-10-04T12:13:45.479Z"导致NA.

是否有一种解决方案也适用于两种格式混合的大数据框架?


我们可以使用%OS代替%S以秒为单位计算小数。

help("strptime")

具体到 R 是%OSn,对于输出,将秒数截断为 0

as.POSIXct(time, format="%Y-%m-%dT%H:%M:%OSZ")
# [1] "2018-07-29 15:02:05 CEST" "2018-07-29 14:46:57 CEST"
# [3] "2018-10-04 12:13:41 CEST" "2018-10-04 12:13:45 CEST"

这个基本 R 代码是快得多比包装解决方案,您自己尝试一下。

Update 1

time2 <- c("2018-09-01T12:42:37.000+02:00", "2018-10-01T11:42:37.000+03:00")

这个比较棘手。?strptime说我们应该使用%z对于 UTC 的偏移量,但不知怎的,它不起作用as.POSIXct。相反,我们可以这样做,

as.POSIXct(substr(time2, 1, 23), format="%Y-%m-%dT%H:%M:%OS") + 
  {os <- as.numeric(el(strsplit(substring(time2, 24), "\\:")))
  (os[1]*60 + os[2])*60}
# [1] "2018-09-01 14:42:37 CEST" "2018-10-01 13:42:37 CEST"

它从字符串中删除不可读的部分,将其转换为秒并将其添加到"POSIXct" object.

如果有only小时如time2,我们也可以说:

as.POSIXct(substr(time2, 1, 23), format="%Y-%m-%dT%H:%M:%OS") + 
  as.numeric(substr(time2, 24, 26))*3600
# [1] "2018-09-01 14:42:37 CEST" "2018-10-01 13:42:37 CEST"

现在代码稍微长了一点,但这并不能掩盖这样一个事实:它的运行速度实际上与答案顶部的代码一样快。

Update 2

您可以将当前的三个变体包装到一个函数中if (nchar(x) == 29) ... else结构,比如这样的:

fixDateTime <- function(x) {
  s <- split(x, nchar(x))
  if ("20" %in% names(s))
    s$`20` <- as.POSIXct(s$`20` , format="%Y-%m-%dT%H:%M:%SZ")
  else if ("24" %in% names(s))
    s$`24` <- as.POSIXct(s$`24`, format="%Y-%m-%dT%H:%M:%OSZ")
  else if ("29" %in% names(s))
    s$`29` <- as.POSIXct(substr(s$`29`, 1, 23), format="%Y-%m-%dT%H:%M:%OS") + 
      {os <- as.numeric(el(strsplit(substring(s[[3]], 24), "\\:")))
      (os[1]*60 + os[2])*60}
  return(unsplit(s, nchar(x)))
}

res <- fixDateTime(time3)
res
# [1] "2018-07-29 15:02:05 CEST" "2018-10-04 00:00:00 CEST" "2018-10-01 00:00:00 CEST"
str(res)
# POSIXct[1:3], format: "2018-07-29 15:02:05" "2018-10-04 00:00:00" "2018-10-01 00:00:00"

仅与套餐相比fixDateTime可以处理所有三种定义的日期时间类型。根据最终的基准测试,该功能仍然非常快。

Note:如果不同的日期格式具有相同的值,则该函数在逻辑上会失败nchar,并且应该根据情况进行定制(例如由另一个split健康)状况)!未测试:添加秒数时的夏令时行为POSIXct.

基准

# Unit: milliseconds
#        expr       min        lq      mean    median        uq       max neval  cld
# fixDateTime  35.46387  35.94761  40.07578  36.05923  39.54706  68.46211    10   c 
#  as.POSIXct  20.32820  20.45985  21.00461  20.62237  21.16019  23.56434    10  b   # to compare
#   lubridate  11.59311  11.68956  12.88880  12.01077  13.76151  16.54479    10 a    # produces NAs! 
#     anytime 198.57292 201.06483 203.95131 202.91368 203.62130 212.83272    10    d # produces NAs!

Data

time <- c("2018-07-29T15:02:05Z", "2018-07-29T14:46:57Z", "2018-10-04T12:13:41.333Z", 
"2018-10-04T12:13:45.479Z")
time2 <- c("2018-07-29T15:02:05Z", "2018-07-29T15:02:05Z", "2018-07-29T15:02:05Z") 
time3 <- c("2018-07-29T15:02:05Z", "2018-10-04T12:13:41.333Z", 
           "2018-10-01T11:42:37.000+03:00") 

基准代码

n <-  1e3
t1 <- sample(time2, n, replace=TRUE)
t2 <- sample(time3, n, replace=TRUE)

library(lubridate)
library(anytime)
microbenchmark::microbenchmark(fixDateTime=fixDateTime(t2),
                               as.POSIXct=as.POSIXct(t1, format="%Y-%m-%dT%H:%M:%OSZ"),
                               lubridate=parse_date_time(t2, "ymd_HMS"),
                               anytime=anytime(t2),
                               times=10L)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何快速转换大数据帧中的不同时间格式? 的相关文章

  • 为什么在 R 中绘图时,hovertemplate 无法正确显示某些数据点

    mydat2 lt data frame subject c math english chemistry score c 80 50 65 class c A B A count c 50 60 70 library plotly plo
  • Dplyr 过滤多个类似条件

    我正在尝试在 dplyr 中做一个过滤器 其中的列就像某些观察结果 我可以使用 sqldf 作为 Test lt sqldf select from database Where SOURCE LIKE ALPHA OR SOURCE LI
  • 使用 sprintf 打印换行符 - 有光泽

    我试图在打印时进行换行 这是我的代码 temp lt LETTERS 1 11 print sprintf Rank s s n 1 11 temp output 1 Rank 1 A n Rank 2 B n Rank 3 C n Ran
  • 记录类名、方法名和行号的性能影响

    我正在我的 java 应用程序中实现日志记录 以便我可以调试应用程序投入生产后可能出现的潜在问题 考虑到在这种情况下 人们不会奢侈地使用 IDE 开发工具 以调试模式运行事物或单步执行完整代码 因此在每条消息中记录类名 方法名和行号将非常有
  • 在 mutate pipeline 中按组获取唯一 ID [重复]

    这个问题在这里已经有答案了 自从新的 dplyr v1 0 0 更新发布以来 我注意到该功能group indices 有 已弃用 我在工作中经常使用这个功能 并且我喜欢在mutate 例如使用dplyr v0 8 3我能够非常轻松地做这样
  • MATLAB 中的逻辑数组与数值数组

    我正在比较两个二进制数组 我有一个数组 其中值可以是一或零 如果值相同则为 1 如果不同则为零 请注意 我正在做检查之外的其他事情 因此我们不需要进入矢量化或代码的性质 在 MATLAB 中使用数值数组和逻辑数组哪个更有效 Logical
  • 每个 mmap/access/munmap 两次 TLB 未命中

    for int i 0 i lt 100000 i int page mmap NULL PAGE SIZE PROT READ PROT WRITE MAP ANONYMOUS MAP PRIVATE 1 0 page 0 0 munma
  • 根据 R 中的另一个变量过滤簇中的 id

    我有 100 名患者的数据 每个患者都有 7 天 1 到 7 的值 如何仅在第一天根据另一个变量选择患者 df lt data frame id c 1 1 1 2 2 2 day c 1 2 3 1 2 3 RRT c 0 1 0 1 0
  • 使用 R 进行语言相关排序

    1 如何正确排序 任务是根据英文字母对美国州名缩写进行排序 但我注意到 R 根据某种操作系统语言或区域设置对列表进行排序 例如 在我的语言 立陶宛语 中 甚至拉丁语 非立陶宛语 字母的顺序也与英语字母表中的顺序不同 仅比较两个字母表中的非立
  • 词云中的空格

    我目前将 wordle 用于词云的许多艺术用途 我认为 R 的词云可能具有更好的控制能力 1 如何在词云中保持单词大写 解决了 2 如何将两个单词作为一个块保留在词云中 wordle 使用 运算符来完成此操作 R 的词云仅按原样打印 例如
  • JTable 不断调用自定义单元格渲染器方法...

    编译源可以在以下位置找到 http www splashcd com jtable tar http www splashcd com jtable tar 我是这门语言的新手 所以我不确定这是否可以接受 我创建了一个 JTable 来为收
  • 相对于时间求平均值

    我有以下带有日期时间和相应值的数据集 时间间隔为每10分钟一次 我需要以 15 分钟的间隔生成新行 例如 15 40 的值为 599 15 50 的值为 594 因此需要在两者之间生成一个新行 即 15 45 的平均值为 599 和 594
  • Postgres 性能问题

    我们正在运行 Postgres 9 1 3 最近我们的一台服务器开始遇到重大性能问题 我们的查询在一段时间内运行良好 但截至 8 月 1 日 速度显着减慢 看起来大多数有问题的查询都是 Select 查询 带有 count 的查询尤其糟糕
  • 如何在 R 中压缩多个 CSV 文件?

    我正在尝试在 R 中压缩多个 CSV 文件 下面是供参考的代码 Create two dataframes using inbuilt datasets for reproducible code df1 lt head mtcars df
  • 在r中水平旋转直方图

    谁能帮我如何在 r 中将直方图旋转 90 度 我知道箱线图中有一个选项 horiz T 但我不知道直方图是否有类似的选项 我认为你必须使用 hist 和 barplot 来完成它 如下所示 直接来自文档 你可以在这里检查它 layout x
  • 使用条件求 R 中的累积和

    我需要创建一个新变量 其中包含每个 ID 过去三年金额的总和 如果没有三年的数据 则应显示 NA 举个例子 ID YEAR AMOUNT 1 2010 5 1 2011 2 1 2012 4 1 2013 1 1 2014 3 2 2013
  • 性能 多次插入或多值单次插入

    从性能角度 时间和服务器负载 来看 最好是进行多个插入或单个插入多个值 我在 stackoverflow 上发现每次插入最多可以有 1000 个值集 我说的是两种情况 要插入大约 1000 3000 个值 有时我会在 mySQL 数据库中插
  • 从R中的序列中随机提取多个连续项

    Frag lt seq 1 30000 K lt 9 P lt sample 1 K 1 sys sample lt Frag seq P length Frag K 现在 sys sample 包含 3333 个数字 如何在R中随机提取1
  • 使用 Nexus 10 在 Android 4.3 上滚动时性能不佳

    我的应用程序有一个带有一些滚动的列表视图 在我测试过的所有手机 Nexus One Nexus 4 和 Galaxy S3 4 上都表现得非常好 以 60fps 滚动 但 Nexus 10 上的表现很糟糕 大概在 15fps 左右 我已经将
  • 如何从线性模型 (lm) 预测 x 值

    我有这个数据集 x lt c 0 40 80 120 160 200 y lt c 6 52 5 10 4 43 3 99 3 75 3 60 我使用计算了一个线性模型lm model lt lm y x 我想知道的预测值x如果我有新的y值

随机推荐