Bardzo szybko czytam dane, używając nowego arrow
pakietu. Wydaje się, że jest na dość wczesnym etapie.
W szczególności używam parkietowego formatu kolumnowego. To konwertuje z powrotem nadata.frame
R, ale możesz uzyskać jeszcze głębsze przyspieszenia, jeśli tego nie zrobisz. Ten format jest wygodny, ponieważ można go również używać z języka Python.
Mój główny przypadek użycia tego jest na dość ograniczonym serwerze RShiny. Z tych powodów wolę trzymać dane dołączone do aplikacji (tj. Poza SQL), a zatem wymagają małego rozmiaru pliku i szybkości.
Ten powiązany artykuł zawiera analizę porównawczą i dobry przegląd. Poniżej zacytowałem kilka interesujących punktów.
https://ursalabs.org/blog/2019-10-columnar-perf/
Rozmiar pliku
Oznacza to, że plik Parquet jest o połowę mniejszy niż nawet skompresowany plik CSV. Jednym z powodów, dla których plik Parquet jest tak mały, jest kodowanie słownikowe (zwane również „kompresją słownikową”). Kompresja słownikowa może zapewnić znacznie lepszą kompresję niż przy użyciu kompresora bajtów ogólnego przeznaczenia, takiego jak LZ4 lub ZSTD (które są używane w formacie FST). Parkiet został zaprojektowany do produkcji bardzo małych plików, które można szybko odczytać.
Czytaj prędkość
Kiedy kontrolujemy według rodzaju wyjścia (np. Porównując ze sobą wszystkie dane wyjściowe R data.frame), widzimy, że wydajność Parquet, Feather i FST mieści się w granicach stosunkowo niewielkiego marginesu. To samo dotyczy wyników pandas.DataFrame. data.table :: fread jest imponująco konkurencyjny w stosunku do rozmiaru pliku 1,5 GB, ale opóźnia się w stosunku do 2,5 GB CSV.
Niezależny test
Przeprowadziłem niezależne testy porównawcze na symulowanym zbiorze danych obejmującym 1 000 000 wierszy. Zasadniczo przetasowałem kilka rzeczy, aby spróbować zakwestionować kompresję. Dodałem również krótkie pole tekstowe z losowymi słowami i dwoma symulowanymi czynnikami.
Dane
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))
)
Czytaj i pisz
Zapisywanie danych jest łatwe.
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)
Odczytywanie danych jest również łatwe.
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)
Przetestowałem czytanie tych danych w stosunku do kilku konkurencyjnych opcji i uzyskałem nieco inne wyniki niż w powyższym artykule, który jest oczekiwany.
Ten plik nie jest tak duży jak artykuł porównawczy, więc może to jest różnica.
Testy
- rds: test_data.rds (20,3 MB)
- parquet2_native: (14,9 MB z wyższą kompresją i
as_data_frame = FALSE
)
- parquet2: test_data2.parquet (14,9 MB z wyższą kompresją)
- parkiet: test_data.parquet (40,7 MB)
- fst2: test_data2.fst (27,9 MB z wyższą kompresją)
- fst: test_data.fst (76,8 MB)
- fread2: test_data.csv.gz (23,6 MB)
- fread: test_data.csv (98,7 MB)
- pióro_arrow: test_data.feather (157,2 MB czytane z
arrow
)
- pióro: test_data.feather (157,2 MB czytane za pomocą
feather
)
Spostrzeżenia
W przypadku tego konkretnego pliku fread
jest on naprawdę bardzo szybki. Podoba mi się mały rozmiar pliku z wysoce skompresowanego parquet2
testu. Mogę poświęcić czas na pracę z rodzimym formatem danych, a nie zdata.frame
jeśli naprawdę potrzebuję przyspieszenia.
Tutaj fst
jest również doskonałym wyborem. Używałbym mocno skompresowanego fst
formatu lub wysoce skompresowanego, w parquet
zależności od tego, czy potrzebuję kompromisu prędkości lub rozmiaru pliku.