2016-02-24 1 views
0

J'ai plusieurs gros rasters au format GeoTIFF.Comment écrire de gros rasters dans une table ou une base de données en utilisant R?

Les dimensions sont 34565, 116908, 4 040 925 020 (nrow, ncol, Ncell) de chaque (recouvrement parfait), les valeurs sont de différents types: entier, flotteur ...

Comment puis-je écrire ces raster valeurs dans une table ou une base de données en utilisant R (ou un autre logiciel), donc plus tard je peux l'analyser en utilisant Spark, python ou R?

je vais devoir traiter plusieurs rasters, donc la table idéalement sortie ressembler à:

row  column  raster1.value raster2.value raster3.value 
1  1   56    76    100 
1  2   18    45    89 
...  ...  ...   ...   ... 

34656 116908  23    39    43 

j'évaluer dans le calcul de l'installation avec 32 cœurs et 128 Go de RAM. Ainsi, le calcul parallèle est également possible.

Je serai très reconnaissant pour votre aide!

+0

Merci pour votre réponse! _quelqu'un a supprimé son commentaire_ J'ai besoin que les données soient dans un format de table, parce que ** (1) ** Je veux utiliser le paquetage data.table de R avec ses propriétés 'pass-by-reference' (ou, peut-être, même Spark) ; ** (2) ** J'ai besoin de sous-ensembles d'enregistrements basés sur une clé (indexation), ce que je ne peux pas faire efficacement, si les données sont dans un format raster; ** (3) ** travailler avec des tables, des matrices, des bases de données est beaucoup plus rapide qu'avec des rasters. ** A propos du format long-large. ** Je préfère le format large car je veux effectuer un calcul pour chaque cellule en utilisant des valeurs de tous les rasters (par exemple, raster1.value + raster2.value/raster3.value). – enya

+0

J'ai supprimé le commentaire après avoir relu votre question: je pense que c'est clair comme ça. Juste une question, vos rasters sont-ils uniques ou multi-bandes ?, sont-ils aussi nommés de telle sorte que leur ordre peut être déterminé à partir du nom seul? Bravo – shekeine

+0

Vos opérations seraient beaucoup plus efficaces si elles étaient effectuées dans le paquet raster. Je comprends votre besoin d'indexation, mais il y a aussi la possibilité de le faire dans raster (par exemple., X [i, j] où i = row, j = col). La façon dont vous envisagez les données est très inefficace et produirait un tableau absurdement grand. Lorsque vous entrez dans les données, les avantages d'utiliser quelque chose comme data.table sont perdus. En outre, vous pouvez avoir beaucoup de RAM, mais vous devez toujours tenir compte de l'exploitation sur les données et ne pas simplement le persister. –

Répondre

0
#Load libs 
library(doParallel) 
library(parallel) 
library(foreach) 
library(data.table) 

Supposant vous n rasters, situé dans myras/,

#List of paths to rasters 
raspaths <- list.files('myras', pattern='.tif$', full.names=T) 

#Register cluster for parallel processing: Cores to use: all except 1 
cl <- makeCluster(detectCores() - 1) 
registerDoParallel(cl, cores=detectCores() - 1) 

#Raster to datatable in parallel: one raster per thread 
dtlist <- foreach (ras_id=raspaths, .packages=c('raster', 'data.table'), .combine='c') %dopar% { 

      #Read all rasters into one big stack 
      ras <- raster(ras_id) 

      #get column and row indices 
      ridx <- rowFromCell(object=ras, cell=1:ncell(ras)) 
      cidx <- colFromCell(object=ras, cell=1:ncell(ras)) 

      #Convert to data.frame then to data.table (slowest part, perhaps someone here knows a better way?) 
      dt <- data.table(as.data.frame(ras)) 

      #Set key 
      setkey(dt) 

      #Add row and column info 
      dt[, c('row', 'column'):=list(ridx, cidx)] 

      #Some column ordering 
      setcolorder(x=dt, c("row", "column", names(dt)[1])) 
      list(dt) 
} 
stopCluster(cl) 

#Bind all per-raster datatables into one big table 
big_dt <- rbindlist(dtlist, fill=T, use.names=T) 

#Write to disk as comma separated text file which can then be read into any Database e.g. Postgresql 
write.csv(x=dt, file='mybigtable.csv', row.names=F) 

écriture à csv comme l'étape finale n'est pas la seule option. Avec RPostgresql, vous pouvez également exporter "big_dt" directement dans une relation dans une instance postgres locale ..

+0

Merci pour votre commentaire. La conversion __data.table (as.data.frame (big_stack)) __ est le goulot d'étranglement de la tâche, je me bats avec.Il devrait y avoir un moyen de lire les données pièce par pièce et de les écrire quelque part (peut-être dans une base de données?). Je peux commencer à lire les parties de rasters en parallèle, mais j'ai besoin de trouver un moyen d'écrire ces données de manière efficace quelque part déjà dans la structure de la table. – enya

+0

Eh bien, les fonctions 'raster' et' stack' tronquent déjà le processus de lecture lors de la lecture des données dans R afin que U puisse également paralléliser la lecture et la conversion à data.table sur plusieurs rasters à la place. Vous finiriez avec une grande liste de data.tables où chacun provient d'un raster. U peut alors écrire dans un gros fichier texte pour l'importer dans une instance de serveur Postgres que vous avez déjà configurée ou l'exporter directement dans une base de données. Je ne pense pas que le dernier bit est parallélisable (écrire dans le fichier/exporter le résultat vers la base de données). – shekeine