【问题标题】:How to divide data frame in r in groups of equal number of records and split dat randomly & equally in two data frames如何将 r 中的数据帧分成相等数量的记录组,并在两个数据帧中随机平均分割数据
【发布时间】:2019-11-15 16:57:02
【问题描述】:

我有一些包含大约 30000 条记录的数据。我想将数据分成 288 条记录组。然后将数据排序到 test_data 和 train_data 单独的数据帧中,其中前 4 条记录存储到 train_data 中,而第 5 条记录存储到 test_data 中,顺序和随机。 5 天中的任何一天以某种方式随机保存到 test_data 中,其余 4 天保存到 train_data 中。

如何做到这一点?

样本数据:

 #   timestamp               var1      var2
    --------------------------------------
 1   01-01-2019 18:00:00      1.2       21
 2   01-01-2019 18:05:00      2.3       32
 3   01-01-2019 18:10:00      3.4       43
 4   01-01-2019 18:15:00      4.5       54
 5   01-01-2019 18:20:00      5.6       65
 . 
 .
 .
3000  ..   -    ..   ..        ..        ..

样本输出:

#in case of sequencial OR contiguous division  
train_data = (#1,#2,#3,#4 .... #1152,#1441,......,#2592,...) 
test_data = (€253,#254,.....,#1440,.....,#2593,....)

#in case of random division, any 288 contiguous records from bunch of 5 in to #test_data and 4x288 into train_data.

目前我有这种数据拆分方法。

   set.seed(100)

    train <- sample(nrow(dataset1), 0.7 * nrow(dataset1), replace = FALSE)
    TrainSet <- dataset1[train,]
    #scale (TrainSet, center = TRUE, scale = TRUE)
    ValidSet <- dataset1[-train,]
    #scale (ValidSet, center = TRUE, scale = TRUE)
    summary(TrainSet)
    summary(ValidSet)

【问题讨论】:

  • 我不确定您所说的“随机和平等”是什么意思。您想首先将数据框拆分为一组较小的数据框,每个数据框有 288 条记录,对吗?然后你想把每一个分成两组,训练和测试?您介意用所需输出的实际示例以及您尝试过的代码来澄清问题吗?
  • @Aziz:基本上,当我输入一些样本数据时,我的数据是每小时每 5 分钟记录一次的观察结果。所以每天有 288 次观察。我想分发数据 4 天用于训练,1 天用于测试数据。所以通过将数据分成288条记录,我认为可以实现。不将数据拆分为 288 条记录的数据帧,而是以 288 条记录为单位或组,代表 1 天。我添加的示例输出和用于采样数据的代码。
  • 30,000 个观察值代表 104 或 105 天,您想要一个大约 84 天的训练集和一个 20-21 天的测试集?但是样本应该是系统未对齐的,也就是说每组 5 天,一个去测试,另外四个去训练?
  • 如果我理解正确的话,您希望将同一天的数据保存在一起,但希望将您的“天”分成两组,80% 用于训练,20% 用于测试?
  • @Aziz:完全一样

标签: r random sampling


【解决方案1】:

这能实现你想要的吗?

dat$day <- as.Date(timestamp, "%d-%m-%Y")  # Add the day for each observation
days <- unique(dat$day)                    # Get the days since it is the sampling unit
groups <- seq(1, 105, by=5)                # Assuming 30240 observations, 105 days
daystest <- sample(5, length(groups), replace=TRUE) + groups
datetest <- days[daystest]                 # Days in the test set
Testing <- dat[dat$day %in% datetest,]         # Test data set
Training <- dat[!dat$day %in% datetest,]

Testing是用于测试的原始数据的数据文件,Training是用于训练的原始数据的数据文件。由于您没有包含可重现的数据样本,因此我无法对其进行测试。

【讨论】:

  • > 测试
  • 信息不足。正如我所说,如果没有可重复的示例,我将无法进行测试。如果没有可重现的示例,我也无法调试。获取该错误消息的一种方法是如果dat 是向量而不是数据框。我打电话给你的数据dat。你有吗?
  • 对此感到抱歉。不,我没有调用我的数据数据。相反,我认为时间戳是来自我的数据,因为这是我们用来将数据划分为天的东西。
【解决方案2】:

这是一种方法:

# assume the number of rows is divisible by 288
num_days = nrow(dataset1)/288

# Each value (True or False) indicates whether the *day* is included or not 
training.days.mask = sample(rep(c(T,T,T,T,F), length.out=num_days))

# To index the actual values, repeat each mask 288 times
training.samples.mask = rep(training.days.mask, each=288)

# now use the mask to extract the data
training.samples = dataset1[training.samples.mask,]
testing.samples = dataset1[!training.samples.mask,]

这个想法是首先对日索引(不是样本)执行sample。然后,将每个掩码重复 288 次以捕获一整天的样本。

【讨论】:

  • 这将比我的方法更快,但是如果您的观察结果有任何差距,它将失败(例如,某些日子少于 288 个观察结果,除非缺失的观察结果在数据框中表示为 NA) .
  • @dcarlson:是的,我假设数据是完整的,每天的样本数正好是 288,并且天数可以被 5 整除(得到 4:1 的训练-测试比率)。你的方法肯定更健壮:)
  • 没有遗漏的观察结果。缺少数据的字段标记为NA
  • 它基本上不起作用。它在 9000 次观测中省略了大约 2000 天。但是如果看到数据,它包含连续的天,而不是省略第 5 天。并且测试数据,即测试样本是空数据框。
  • @XCeptable 代码有错字。我已对其进行了更新以创建单个掩码(用于训练数据),然后将其反转以获取测试数据。它现在正在工作。
猜你喜欢
  • 2017-10-17
  • 2020-02-05
  • 1970-01-01
  • 2019-05-06
  • 2020-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多