首页 > 解决方案 > split() 函数执行缓慢

问题描述

我有一个包含大约 200.000 行事务的 csv 文件。这是数据的导入和少量预处理:

data <- read.csv("bitfinex_data/trades.csv", header=T)
data$date <- as.character(data$date)
data$date <- substr(data$date, 1, 10)
data$date <- as.numeric(data$date)
data$date <- as.POSIXct(data$date, origin="1970-01-01", tz = "GMT")

head(data)

id          exchange  symbol                date price     amount  sell
1 24892563       bf   btcusd 2018-01-02 00:00:00 13375 0.05743154 False
2 24892564       bf   btcusd 2018-01-02 00:00:01 13374 0.12226129 False
3 24892565       bf   btcusd 2018-01-02 00:00:02 13373 0.00489140 False
4 24892566       bf   btcusd 2018-01-02 00:00:02 13373 0.07510860 False
5 24892567       bf   btcusd 2018-01-02 00:00:02 13373 0.11606086 False
6 24892568       bf   btcusd 2018-01-02 00:00:03 13373 0.47000000 False

我的目标是获得每小时交易代币的总和。为此,我需要按小时拆分数据,我通过以下方式进行了拆分:

tmp <- split(data, cut(data$date,"hour"))

但是,这花费的时间太长(最多 1 小时),我想知道这是否是函数的正常行为,例如split()and cut()?有没有使用这两个功能的替代方法?

更新:

在使用@Maurits Evers 的好建议后,我的输出表如下所示:

# A tibble: 25 x 2
   date_hour     amount.sum
   <chr>              <dbl>
 1 1970-01-01 00       48.2
 2 2018-01-02 00     2746. 
 3 2018-01-02 01     1552. 
 4 2018-01-02 02     2010. 
 5 2018-01-02 03     2171. 
 6 2018-01-02 04     3640. 
 7 2018-01-02 05     1399. 
 8 2018-01-02 06      836. 
 9 2018-01-02 07      856. 
10 2018-01-02 08      819. 
# ... with 15 more rows

这正是我想要的,期望第一行,日期从 1970 年开始。关于可能导致问题的任何建议?我试图更改as.POSIXct()函数的 origin 参数,但这并没有解决问题。

标签: r

解决方案


我同意@Roland 的评论。为了说明,这里有一个例子。

  1. 让我们在一分钟的时间间隔内生成一些包含 200000 个条目的数据。

    set.seed(2018);
    df <- data.frame(
        date = seq(from = as.POSIXct("2018-01-01 00:00"), by = "min", length.out = 200000),
        amount = runif(200000))
    head(df);
    #                 date     amount
    #1 2018-01-01 00:00:00 0.33615347
    #2 2018-01-01 00:01:00 0.46372327
    #3 2018-01-01 00:02:00 0.06058539
    #4 2018-01-01 00:03:00 0.19743361
    #5 2018-01-01 00:04:00 0.47431419
    #6 2018-01-01 00:05:00 0.30104860
    
  2. 我们现在 (1) 创建一个新列date_hour,其中包括完整日期和时间的日期和小时部分,(2)group_bydate_hour,以及 (3) 列中的总和条目amountamount.sum

    df %>%
        mutate(date_hour = format(date, "%Y-%m-%d %H")) %>%
        group_by(date_hour) %>%
        summarise(amount.sum = sum(amount))
    ## A tibble: 3,333 x 2
    #   date_hour     amount.sum
    #   <chr>              <dbl>
    # 1 2018-01-01 00       28.9
    # 2 2018-01-01 01       26.4
    # 3 2018-01-01 02       32.7
    # 4 2018-01-01 03       29.9
    # 5 2018-01-01 04       29.7
    # 6 2018-01-01 05       28.5
    # 7 2018-01-01 06       34.2
    # 8 2018-01-01 07       33.8
    # 9 2018-01-01 08       30.7
    #10 2018-01-01 09       27.7
    ## ... with 3,323 more rows
    

这非常快(在我的 2012 MacBook Air 上大约需要 0.3 秒),您应该能够根据您的特定情况轻松调整此示例。


推荐阅读