【发布时间】:2023-03-14 11:01:03
【问题描述】:
我正在尝试构建一个快速的 CSV 到 Vowpal 输入格式转换器。我找到了一些与libsvm 相关的好代码,并以此为基础。它适用于提供的小型泰坦尼克号数据集,但我的真实数据集超过 450 万。具有 200 多个特征的观察结果。在功能强大的服务器上提供代码需要三天时间。
有没有办法去掉这里的单循环?请记住,Vowpal 有其自己的稀疏性,因此代码需要每次检查索引以排除每行上的 0 或 NA。 (与数据框不同,vowpal 不需要在每行中保留相同数量的特征)。我可以将每一行写入文件而不是将其全部保存在内存中。任何解决方案将不胜感激!
# sample data set
titanicDF <- read.csv('http://math.ucdenver.edu/RTutorial/titanic.txt',sep='\t')
titanicDF <- titanicDF [c("PClass", "Age", "Sex", "Survived")]
# target variable
y <- titanicDF$Survived
lineHolders <- c()
for ( i in 1:nrow( titanicDF )) {
# find indexes of nonzero values - anything
# with zero for that row needs to be ignored!
indexes = which( as.logical( titanicDF [i,] ))
indexes <- names(titanicDF [indexes])
# nonzero values
values = titanicDF [i, indexes]
valuePairs = paste( indexes, values, sep = ":", collapse = " " )
# add label in the front and newline at the end
output_line = paste0(y[i], " |f ", valuePairs, "\n", sep = "" )
lineHolders <- c(lineHolders, output_line)
}
【问题讨论】:
-
至少预先分配
lineHolders。在 R 中增长对象是你可能做的最不明智的事情。其他想法:以矢量化方式预先添加标签,以及将粘贴在一起的所有其他部分。然后重新组织列表中的所有内容并使用lapply。 -
如果速度很重要,R 不会是我重塑这样一个文本文件的首选。 Python 或 Perl 可能会更快地完成它。但是你有没有分析过这段代码?不保证删除循环会使任何事情变得更快。下一个最好的事情是拆分文件并并行转换块。然后,您可以根据可以访问的处理器数量减少时间。
-
谢谢大家 - 原始的 libsvm 脚本将每一行写入文件,避免了内存问题。如果我能找到解决并发磁盘写入的好方法,我可能不得不尝试分布式任务。感谢您的意见!
-
可能更容易将所需的列写入新的 .csv 并使用 phraug,这是大众汽车人自己为转换编写的工具 - github.com/zygmuntz/phraug
-
我不会复制/粘贴,但我创建了一个solution using
fwrite并在这里按列操作......到目前为止我看到的例子仍然很慢......
标签: r csv vowpalwabbit