R:Оптимизация/Импорт данных — различия между версиями
м (→Функция read.table()) |
м (→Импорт CSV) |
||
Строка 81: | Строка 81: | ||
По результатам сравнения, можем заключить, что указание специфических аргументов функции <code>read.table()</code> позволяет существенно ускорить процесс импорта данных в формате CSV. | По результатам сравнения, можем заключить, что указание специфических аргументов функции <code>read.table()</code> позволяет существенно ускорить процесс импорта данных в формате CSV. | ||
+ | |||
+ | === Функция <code>fread()</code> === | ||
+ | |||
+ | Пакет {{r-package|data.table}}, помимо прочих полезных вещей, включает в себя функцию для чтения данных - <code>fread()</code>. Стоит отметить, что полученная в результате импорта переменная будет иметь класс <code>data.table</code>, что предполагает определённую специфику работы с ней<ref>Синтаксис работы с классом <code>data.table</code> отличен от синтаксиса работы с матрицами и таблицами данных в R.</ref>. | ||
+ | |||
+ | Сравним результаты работы функций <code>read.table()</code> и <code>fread()</code>: | ||
+ | |||
+ | {{r-code|code=<nowiki>> library(data.table) | ||
+ | > microbenchmark(defaults = read.table(tmp.csv, sep = ";", header = TRUE), | ||
+ | + ompimize = read.table(tmp.csv, sep = ";", header = TRUE, | ||
+ | + colClasses = c("integer", "integer", "factor", "numeric", "numeric", "numeric"), | ||
+ | + nrows = N, comment.char = "", quote=""), | ||
+ | + data.table = fread(tmp.csv, sep = ";", header = TRUE)) | ||
+ | Unit: milliseconds | ||
+ | expr min lq median uq max neval | ||
+ | defaults 5344.4 8063.6 8513.6 8853.0 13602.0 100 | ||
+ | ompimize 2839.3 2856.9 2896.7 3203.7 3573.5 100 | ||
+ | data.table 526.6 528.2 535.9 578.2 932.3 100</nowiki>}} | ||
+ | |||
+ | == Примечания == | ||
+ | |||
+ | <references /> | ||
[[Категория:R]] | [[Категория:R]] | ||
[[Категория:Оптимизация кода]] | [[Категория:Оптимизация кода]] |
Версия 17:36, 5 апреля 2014
При обработке данных большого объёма имеет смысл импортировать только ту часть данных, которая непосредственно участвует в обработке. Это целесообразно как с точки зрения расхода оперативной памяти, так и скорости выполнения операций поиска, сортировки и фильтрации данных.
Импорт CSV
Функция read.table()
Для импорта файлов CSV в R предусмотрена функция read.table()
и функци-обёртка (wrapper) read.csv()
. С точки зрения скорости работы, параметры функции read.table()
, заданные по умолчанию, не являются оптимальными. Приведём несколько рекомендаций по использованию функции read.table()
:
- указать тип переменных, содержащихся в таблице с помощью аргумента
colClasses
; - указать количество импортируемых строк с помощью аргумента
nrows
; - отключить поиск комментариев с помощью аргумента
comment.char = ""
.
Создадим таблицу данных содержащую [math]10^{6}[/math] строк и 6 столбцов:
<syntaxhighlight lang="r">> N <- 10^6L # задаём количество наблюдений > DF <- data.frame(a = sample(1:10^3L, N, replace = TRUE), b = sample(1:10^3L, N, replace = TRUE), c = sample(LETTERS[1:10], N, replace = TRUE), e = rnorm(N), d = rnorm(N, 100, 15), f = runif(N, 0, 10^3L)) </syntaxhighlight>
Рассмотрим таблицу более подробно. Начало таблицы:
<syntaxhighlight lang="r"> head(DF) a b c e d f 1 719 104 C -1.8785 87.22 400.5 2 551 448 H 0.5608 101.14 208.4 3 865 236 I 0.5967 117.80 622.5 4 879 411 B -0.6442 120.39 979.9 5 66 229 E -0.5443 111.78 901.3 6 867 579 I -1.3212 104.93 178.3</syntaxhighlight>
Структура данных:
<syntaxhighlight lang="r">> str(DF) 'data.frame': 1000000 obs. of 6 variables: $ a: int 719 551 865 879 66 867 344 786 898 933 ... $ b: int 104 448 236 411 229 579 718 221 68 275 ... $ c: Factor w/ 10 levels "A","B","C","D",..: 3 8 9 2 5 9 3 6 10 7 ... $ e: num -1.878 0.561 0.597 -0.644 -0.544 ... $ d: num 87.2 101.1 117.8 120.4 111.8 ... $ f: num 400 208 623 980 901 ...</syntaxhighlight>
Типы переменных:
<syntaxhighlight lang="r">> sapply(DF, class) a b c e d f "integer" "integer" "factor" "numeric" "numeric" "numeric"</syntaxhighlight>
Размер объекта в оперативной памяти:
<syntaxhighlight lang="r">> print(object.size(DF), units = "auto") 34.3 Mb</syntaxhighlight>
Сохраним таблицу в csv-файл следующими командами:
<syntaxhighlight lang="r">> tmp.csv <- tempfile(fileext=".csv") # генерируем имя и путь для временного файла > write.table(DF, tmp.csv, sep = ";", row.names = FALSE, quote = FALSE)</syntaxhighlight>
Размер полученного файла составил:
<syntaxhighlight lang="r">> file.info(tmp.csv)$size # размер файла в байтах [1] 61724411 > file.info(tmp.csv)$size / 1024^2 # размер файла в мегабайтах [1] 58.86</syntaxhighlight>
Теперь мы можем сравнить производительность функции read.table()
с параметрами по умолчанию и парамтерами, рекомендованными для увеличения производительности данной функции. Для этого нам понадобится пакет microbenchmark
.
<syntaxhighlight lang="r">> microbenchmark(defaults = read.table(tmp.csv, sep = ";", header = TRUE), + ompimize = read.table(tmp.csv, sep = ";", header = TRUE, + colClasses = c("integer", "integer", "factor", "numeric", "numeric", "numeric"), + nrows = N, comment.char = "", quote="")) Unit: seconds expr min lq median uq max neval defaults 6.772 7.419 8.267 8.914 11.026 100 ompimize 2.761 2.782 2.859 2.924 3.037 100</syntaxhighlight>
Значения для аргумента colClasses
мы получили ранее с помощью команды sapply(DF, class)
.
По результатам сравнения, можем заключить, что указание специфических аргументов функции read.table()
позволяет существенно ускорить процесс импорта данных в формате CSV.
Функция fread()
Пакет data.table
, помимо прочих полезных вещей, включает в себя функцию для чтения данных - fread()
. Стоит отметить, что полученная в результате импорта переменная будет иметь класс data.table
, что предполагает определённую специфику работы с ней[1].
Сравним результаты работы функций read.table()
и fread()
:
<syntaxhighlight lang="r">> library(data.table) > microbenchmark(defaults = read.table(tmp.csv, sep = ";", header = TRUE), + ompimize = read.table(tmp.csv, sep = ";", header = TRUE, + colClasses = c("integer", "integer", "factor", "numeric", "numeric", "numeric"), + nrows = N, comment.char = "", quote=""), + data.table = fread(tmp.csv, sep = ";", header = TRUE)) Unit: milliseconds expr min lq median uq max neval defaults 5344.4 8063.6 8513.6 8853.0 13602.0 100 ompimize 2839.3 2856.9 2896.7 3203.7 3573.5 100 data.table 526.6 528.2 535.9 578.2 932.3 100</syntaxhighlight>
Примечания
- ↑ Синтаксис работы с классом
data.table
отличен от синтаксиса работы с матрицами и таблицами данных в R.