studio - La forma más rápida de leer un subconjunto de filas de un CSV
leer xlsx en r (3)
Aquí hay un archivo con 100000 líneas así:
"","a","b","c"
"1",0.825049088569358,0.556148858508095,0.591679535107687
"2",0.161556158447638,0.250450366642326,0.575034103123471
"3",0.676798462402076,0.0854280597995967,0.842135070590302
"4",0.650981109589338,0.204736212035641,0.456373531138524
"5",0.51552157686092,0.420454133534804,0.12279288447462
$ wc -l d.csv
100001 d.csv
Entonces eso es 100000 líneas más un encabezado. Queremos mantener el encabezado y muestrear cada línea si un número aleatorio de 0 a 1 es mayor que 0.9.
$ awk ''NR==1 {print} ; rand()>.9 {print}'' < d.csv >sample.csv
comprobar:
$ head sample.csv
"","a","b","c"
"12",0.732729186303914,0.744814146542922,0.199768838472664
"35",0.00979996216483414,0.633388962829486,0.364802648313344
"36",0.927218825090677,0.730419414117932,0.522808947600424
"42",0.383301998255774,0.349473554175347,0.311060158303007
y tiene 10027 líneas:
$ wc -l sample.csv
10027 sample.csv
Esto tomó 0.033s de tiempo real en mi caja de 4 yo, probablemente la velocidad HD es el factor limitante aquí. Debe escalar linealmente ya que el archivo se trata estrictamente línea por línea.
A continuación, lea en sample.csv
usando read.csv
o fread
como desee:
> s = fread("sample.csv")
Tengo una csv de 5GB
con 2 millones de filas. El encabezado son strings
separadas por comas y cada fila está dividida por comas en doubles
sin datos perdidos o dañados. Es rectangular
Mi objetivo es leer un 10% al azar (con o sin reemplazo, no importa) de las filas en la memoria RAM lo más rápido posible . Un ejemplo de una solución lenta (pero más rápida que read.csv
) es leer en toda la matriz con fread
y luego mantener un aleatorio 10% de las filas.
require(data.table)
X <- data.matrix(fread(''/home/user/test.csv'')) #reads full data.matix
X <- X[sample(1:nrow(X))[1:round(nrow(X)/10)],] #sample random 10%
Sin embargo, estoy buscando la solución más rápida posible (esto es lento porque primero necesito leer todo, luego recortarlo).
La solución que merece una recompensa dará estimaciones de system.time()
de diferentes alternativas.
Otro:
- Estoy usando Linux
- No necesito exactamente el 10% de las filas. Solo aproximadamente 10%.
Puede usar sqldf::read.csv.sql
y un comando SQL para extraer los datos:
library(sqldf)
write.csv(iris, "iris.csv", quote = FALSE, row.names = FALSE) # write a csv file to test with
read.csv.sql("iris.csv","SELECT * FROM file ORDER BY RANDOM() LIMIT 10")
Sepal_Length Sepal_Width Petal_Length Petal_Width Species
1 6.3 2.8 5.1 1.5 virginica
2 4.6 3.1 1.5 0.2 setosa
3 5.4 3.9 1.7 0.4 setosa
4 4.9 3.0 1.4 0.2 setosa
5 5.9 3.0 4.2 1.5 versicolor
6 6.6 2.9 4.6 1.3 versicolor
7 4.3 3.0 1.1 0.1 setosa
8 4.8 3.4 1.9 0.2 setosa
9 6.7 3.3 5.7 2.5 virginica
10 5.9 3.2 4.8 1.8 versicolor
No calcula el 10% para usted, pero puede elegir el límite absoluto de las filas para devolver.
Creo que esto debería funcionar bastante rápido, pero avíseme ya que aún no lo he intentado con big data.
write.csv(iris,"iris.csv")
fread("shuf -n 5 iris.csv")
V1 V2 V3 V4 V5 V6
1: 37 5.5 3.5 1.3 0.2 setosa
2: 88 6.3 2.3 4.4 1.3 versicolor
3: 84 6.0 2.7 5.1 1.6 versicolor
4: 125 6.7 3.3 5.7 2.1 virginica
5: 114 5.7 2.5 5.0 2.0 virginica
Esto toma una muestra aleatoria de N = 5 para el conjunto de datos del iris
.
Para evitar la posibilidad de usar la fila de encabezado nuevamente, esta podría ser una modificación útil:
fread("tail -n+2 iris.csv | shuf -n 5", header=FALSE)