Ich lese Daten sehr schnell mit dem neuen arrow
Paket. Es scheint in einem ziemlich frühen Stadium zu sein.
Insbesondere verwende ich das Parkett- Säulenformat. Dies konvertiert zurück zu adata.frame
in R , aber Sie können noch tiefere Beschleunigungen erzielen, wenn Sie dies nicht tun. Dieses Format ist praktisch, da es auch von Python aus verwendet werden kann.
Mein Hauptanwendungsfall hierfür ist ein ziemlich zurückhaltender RShiny-Server. Aus diesen Gründen ziehe ich es vor, Daten an die Apps anzuhängen (dh außerhalb von SQL), und benötige daher eine geringe Dateigröße sowie Geschwindigkeit.
Dieser verlinkte Artikel bietet Benchmarking und einen guten Überblick. Ich habe unten einige interessante Punkte zitiert.
https://ursalabs.org/blog/2019-10-columnar-perf/
Dateigröße
Das heißt, die Parkettdatei ist halb so groß wie die komprimierte CSV-Datei. Einer der Gründe, warum die Parkettdatei so klein ist, ist die Wörterbuchcodierung (auch als "Wörterbuchkomprimierung" bezeichnet). Die Wörterbuchkomprimierung kann zu einer wesentlich besseren Komprimierung führen als die Verwendung eines Allzweck-Byteekompressors wie LZ4 oder ZSTD (die im FST-Format verwendet werden). Parkett wurde entwickelt, um sehr kleine Dateien zu erstellen, die schnell zu lesen sind.
Lesegeschwindigkeit
Bei der Steuerung nach Ausgabetyp (z. B. Vergleich aller R data.frame-Ausgaben miteinander) sehen wir, dass die Leistung von Parkett, Feder und FST innerhalb eines relativ kleinen Bereichs voneinander liegt. Gleiches gilt für die Ausgaben von pandas.DataFrame. data.table :: fread ist mit der Dateigröße von 1,5 GB beeindruckend konkurrenzfähig, liegt jedoch bei der 2,5-GB-CSV hinter den anderen zurück.
Unabhängiger Test
Ich habe ein unabhängiges Benchmarking für einen simulierten Datensatz von 1.000.000 Zeilen durchgeführt. Grundsätzlich habe ich ein paar Dinge durcheinander gebracht, um die Komprimierung herauszufordern. Außerdem habe ich ein kurzes Textfeld mit zufälligen Wörtern und zwei simulierten Faktoren hinzugefügt.
Daten
library(dplyr)
library(tibble)
library(OpenRepGrid)
n <- 1000000
set.seed(1234)
some_levels1 <- sapply(1:10, function(x) paste(LETTERS[sample(1:26, size = sample(3:8, 1), replace = TRUE)], collapse = ""))
some_levels2 <- sapply(1:65, function(x) paste(LETTERS[sample(1:26, size = sample(5:16, 1), replace = TRUE)], collapse = ""))
test_data <- mtcars %>%
rownames_to_column() %>%
sample_n(n, replace = TRUE) %>%
mutate_all(~ sample(., length(.))) %>%
mutate(factor1 = sample(some_levels1, n, replace = TRUE),
factor2 = sample(some_levels2, n, replace = TRUE),
text = randomSentences(n, sample(3:8, n, replace = TRUE))
)
Lesen und Schreiben
Das Schreiben der Daten ist einfach.
library(arrow)
write_parquet(test_data , "test_data.parquet")
# you can also mess with the compression
write_parquet(test_data, "test_data2.parquet", compress = "gzip", compression_level = 9)
Das Lesen der Daten ist ebenfalls einfach.
read_parquet("test_data.parquet")
# this option will result in lightning fast reads, but in a different format.
read_parquet("test_data2.parquet", as_data_frame = FALSE)
Ich habe das Lesen dieser Daten anhand einiger konkurrierender Optionen getestet und dabei etwas andere Ergebnisse erzielt als mit dem obigen Artikel, der erwartet wird.
Diese Datei ist bei weitem nicht so groß wie der Benchmark-Artikel. Vielleicht ist das der Unterschied.
Tests
- rds: test_data.rds (20,3 MB)
- parquet2_native: (14,9 MB mit höherer Komprimierung und
as_data_frame = FALSE
)
- parquet2: test_data2.parquet (14,9 MB mit höherer Komprimierung)
- Parkett: test_data.parquet (40,7 MB)
- fst2: test_data2.fst (27,9 MB mit höherer Komprimierung)
- fst: test_data.fst (76,8 MB)
- fread2: test_data.csv.gz (23,6 MB)
- fread: test_data.csv (98,7 MB)
- Federpfeil: test_data.feather (157,2 MB lesen mit
arrow
)
- Feder: test_data.feather (157,2 MB lesen mit
feather
)
Beobachtungen
Für diese bestimmte Datei fread
ist eigentlich sehr schnell. Ich mag die kleine Dateigröße aus dem stark komprimierten parquet2
Test. Ich kann die Zeit investieren, um mit dem nativen Datenformat zu arbeiten, anstatt mit einemdata.frame
wenn ich die Beschleunigung wirklich brauche.
Hier fst
ist auch eine gute Wahl. Ich würde entweder das stark komprimierte fst
Format oder das stark komprimierte Format verwenden, parquet
je nachdem, ob ich den Kompromiss zwischen Geschwindigkeit oder Dateigröße benötigte.