我正在分析一个有200行和1200列的数据集,这个数据集存储在一个.CSV文件中。为了进行处理,我使用R的read.csv()函数读取这个文件。
R需要≈600秒来读取这个数据集。后来,我有了一个想法,我将数据转换到.CSV文件中,并尝试使用read.csv()函数再次读取它。我惊讶地看到≈只花了20秒。正如你所看到的,它比≈快30倍。
我对它进行了验证,以便进行以下迭代:
读取200行和1200列(未转置)
> system.time(dat <- read.csv(file = "data.csv", sep = ",", header = F))
user system elapsed
610.98 6.54 618.42 # 1st iteration
568.27 5.83 574.47 # 2nd iteration
521.13 4.73 525.97 # 3rd iteration
618.31 3.11 621.98 # 4th iteration
603.85 3.29 607.50 # 5th iteration读取1200行200列(转置)
> system.time(dat <- read.csv(file = "data_transposed.csv",
sep = ",", header = F))
user system elapsed
17.23 0.73 17.97 # 1st iteration
17.11 0.69 17.79 # 2nd iteration
20.70 0.89 21.61 # 3rd iteration
18.28 0.82 19.11 # 4th iteration
18.37 1.61 20.01 # 5th iteration在任何数据集中,我们接受行中的观察,列中包含要观察的变量。转置改变了这种数据结构。--尽管它使数据看起来很奇怪,但转换数据以进行处理是一个很好的实践吗?
当我转换数据时,我想知道是什么使R快速读取数据集的。我相信这是因为早期的维度是200 * 1200,在转置手术后变成了1200 * 200。为什么R在我转换数据时读取数据的速度快?
更新:研究与实验
我最初问这个问题是因为我的RStudio需要很长时间来读取和计算一个高维数据集(许多列与行200行,1200列相比)。我在使用内置的R函数read.csv()。我阅读了下面的注释,根据他们的建议,我后来尝试了read.csv2()和fread()函数--它们都工作得很好,但是对于我最初的数据集200行* 1200列,它们执行得很慢,并且读取转换后的数据集更快。
我观察到,这也适用于、observed、和Libre office Calc。我甚至尝试将它打开到崇高文本编辑器中,即使对于这个文本编辑器,读取转置数据也很容易(快速)。我仍然无法弄清楚为什么所有这些应用程序都是这样的。如果您的数据与行相比有许多列,那么所有这些应用程序都会遇到麻烦。
所以总结一下整个故事,我只有三个问题。
我的实验也许帮助我重新发现了一些“已知的”智慧,但我在互联网上找不到任何相关的东西。请分享这些良好的编程/数据分析实践。
发布于 2018-07-08 00:42:02
您的问题基本上是关于:读取长数据集比读取宽数据集?快得多。
我在这里给出的不是最后的答案,而是一个新的起点。
对于任何与性能相关的问题,总是比猜测更好。system.time很好,但它只告诉您总的运行时间,而不是内部如何分割时间。如果您快速浏览了read.table的源代码(read.csv只是read.table的包装器),它包含三个阶段:
scan读取5行数据。我不太清楚这部分的目的;scan读取完整的数据。基本上,这会将您的数据逐列读取到字符串列表中,其中每一列都是“记录”;type.convert隐式转换,或者显式(如果您指定了列类)通过as.numeric、as.Date等进行转换。前两个阶段在C级完成,而最后阶段在R级通过一个for循环遍历所有记录。
一个基本的分析工具是Rprof和summaryRprof。下面是一个非常简单的例子。
## configure size
m <- 10000
n <- 100
## a very very simple example, where all data are numeric
x <- runif(m * n)
## long and wide .csv
write.csv(matrix(x, m, n), file = "long.csv", row.names = FALSE, quote = FALSE)
write.csv(matrix(x, n, m), file = "wide.csv", row.names = FALSE, quote = FALSE)
## profiling (sample stage)
Rprof("long.out")
long <- read.csv("long.csv")
Rprof(NULL)
Rprof("wide.out")
wide <- read.csv("wide.csv")
Rprof(NULL)
## profiling (report stage)
summaryRprof("long.out")[c(2, 4)]
summaryRprof("wide.out")[c(2, 4)]c(2, 4)为所有R级函数提取"by.total“时间,并提供足够的样本和”总CPU时间“(可能低于挂钟时间)。下面是我的英特尔i5 2557m @1.1GHz (涡轮增压禁用),桑迪桥2011年。
## "long.csv"
#$by.total
# total.time total.pct self.time self.pct
#"read.csv" 7.0 100 0.0 0
#"read.table" 7.0 100 0.0 0
#"scan" 6.3 90 6.3 90
#".External2" 0.7 10 0.7 10
#"type.convert" 0.7 10 0.0 0
#
#$sampling.time
#[1] 7
## "wide.csv"
#$by.total
# total.time total.pct self.time self.pct
#"read.table" 25.86 100.00 0.06 0.23
#"read.csv" 25.86 100.00 0.00 0.00
#"scan" 23.22 89.79 23.22 89.79
#"type.convert" 2.22 8.58 0.38 1.47
#"match.arg" 1.20 4.64 0.46 1.78
#"eval" 0.66 2.55 0.12 0.46
#".External2" 0.64 2.47 0.64 2.47
#"parent.frame" 0.50 1.93 0.50 1.93
#".External" 0.30 1.16 0.30 1.16
#"formals" 0.08 0.31 0.04 0.15
#"make.names" 0.04 0.15 0.04 0.15
#"sys.function" 0.04 0.15 0.02 0.08
#"as.character" 0.02 0.08 0.02 0.08
#"c" 0.02 0.08 0.02 0.08
#"lapply" 0.02 0.08 0.02 0.08
#"sys.parent" 0.02 0.08 0.02 0.08
#"sapply" 0.02 0.08 0.00 0.00
#
#$sampling.time
#[1] 25.86因此,读取一个长数据集需要7s CPU时间,而读取一个宽数据集则需要25.86s CPU时间。
乍一看,更多的功能会被广泛报道,这可能会让人感到困惑。实际上,长的和宽的情况都执行相同的函数集,但是长的情况更快,因此许多函数所花费的时间少于采样间隔(0.02s),因此无法测量。
但是无论如何,运行时主要是scan和type.convert (隐式类型转换)。在这个例子中,我们看到
scan基本上都是read.csv的工作对象,但不幸的是,我们无法将这样的时间进一步划分到第一阶段和第二阶段。不要想当然地认为这是理所当然的,因为第一阶段只读5行,所以它会非常快。在调试模式中,我发现这个阶段-1可能需要相当长的时间。那我们下一步该怎么办?
scan中花费的时间,那就太好了;发布于 2018-07-09 21:40:02
宽数据集通常比长数据集(即转置数据集)读入内存的速度慢。这会影响许多读取数据的程序,如R、Python、Excel等,尽管这种描述与R更相关:
NA。这意味着每个列的单元格至少与csv文件中的行数一样多,而在长数据集中,您可能会删除NA值并节省一些空间。由于您的数据集似乎不包含任何NA值,我的预感是,由于第二点,您将看到速度的提高。您可以通过将20列数据集的colClasses = rep('numeric', 20)传递给read.csv或fread,或者将120列的rep('numeric', 120)传递给rep('numeric', 120),从而减少猜测数据类型的开销,从而测试这一理论。
https://stackoverflow.com/questions/51075273
复制相似问题