r - 如何为大型数据集矢量化 R 中的 for 循环
问题描述
我对 R 比较陌生,我有一个关于数据处理的问题。主要问题是数据集太大,我想写一个比for循环更快的向量化函数,但我不知道怎么做。数据是关于电影和用户评分的,格式如下(下图)。
1:
5,3,2005-09-06
1,5,2005-05-13
3,4,2005-10-19
2:
2,4,2005-12-26
3,3,2004-05-03
5,3,2005-11-17
1: 和 2: 代表电影,而其他行代表该电影的用户 ID、用户评分和评分日期(按从左到右的顺序,用逗号分隔)。我想将数据格式化为边缘列表,如下所示:
Movie | User
1: | 5
1: | 1
1: | 3
2: | 2
2: | 3
2: | 5
我编写了下面的代码来执行此功能。基本上,对于每一行,它都会检查其是否为电影 ID(包含“:”)或是否为用户数据。然后,它将电影 ID 和用户 ID 组合为每个电影和用户的两列,然后将其行绑定到一个新的数据帧。同时,它也只绑定那些对一部电影评分为 5 分(满分 5 分)的用户。
el <- data.frame(matrix(ncol = 2, nrow = 0))
for (i in 1:nrow(data))
{
if (grepl(':', data[i,]))
{
mid <- data[i,]
} else(grepl(',', data[i,]))
{
if(grepl(',5,', data[i,]))
{
uid <- unlist(strsplit(data[i,], ','))[1]
add <- c(mid, uid)
el <- rbind(el, add)
}
}
}
但是,我有大约 1 亿个条目,并且 for 循环在整个晚上运行而无法完成。有没有办法加快这个速度?我读到了矢量化,但我不知道如何矢量化这个函数。有什么帮助吗?
解决方案
您可以使用一些正则表达式来完成此操作,为此我将使用stringr 包以及zoo 包中的na.locf。(您必须先安装 stringr 和 zoo)。
首先,我们将设置您的数据,听起来像是在单列数据框中:
data <- read.table(textConnection("1:
5,3,2005-09-06
1,5,2005-05-13
3,4,2005-10-19
2:
2,4,2005-12-26
3,3,2004-05-03
5,3,2005-11-17
"))
然后,您可以按照以下步骤操作(注释中的说明)。
# Pull out the column as a character vector for simplicity
lines <- data[[1]]
library(stringr)
# Figure out which lines represent movie IDs, and extract IDs
movie_ids <- str_match(lines, "(\\d+):")[, 2]
# Fill the last observation carried forward (locf), to find out
# the most recent non-NA value
library(zoo)
movie_ids_filled <- na.locf(movie_ids)
# Extract the user IDs
user_ids <- str_match(lines, "(\\d+),")[, 2]
# For each line that has a user ID, match it to the movie ID
result <- cbind(movie_ids_filled[!is.na(user_ids)],
user_ids[!is.na(user_ids)])
这得到了结果
[,1] [,2]
[1,] "1" "5"
[2,] "1" "1"
[3,] "1" "3"
[4,] "2" "2"
[5,] "2" "3"
[6,] "2" "5"
这段代码最重要的部分是正则表达式的使用,尤其是和括号中的捕获组。有关使用正则表达式的更多信息,请查看本指南。"(\\d+):"
(\\d+),
str_match
推荐阅读
- javascript - 为什么很少有日期格式在 javascript 中不起作用
- javascript - MongoDB,将新值推送到数组而不复制密钥
- javascript - 如何通过没有表单的提交按钮进行 AJAX 调用和 PHP,尤其是 jQuery 代码
- javascript - 展开表格隐藏表格行
- sql - Oracle SELECT - 关于性能的问题
- reactjs - 如何将 Reactjs App 重新部署到 github 页面
- python - 如何在 discord.py 中创建 discord.Permissions 对象?
- python - 物体中心到图像中心的距离
- c# - 将列表框的所有项目发送到列表视图的第一列。但是listview是另一种形式
- tcp - 无法使用 Fluentd @tcp 捕获 syslog 客户端 IP 地址