9 votes

R reticulate, comment effacer un objet python de la mémoire ?

J'ai créé une fonction utilisant certaines fonctionnalités de python via la fonction reticulate et plus particulièrement l'ouverture d'une image en utilisant PIL :

image <- "~/Desktop/image.jpg"
pil.image <- reticulate::import( "PIL.Image", convert = FALSE )
img <- pil.image$open( image )

Je fais ensuite quelques manipulations avec l'image (j'extrais plusieurs cultures), ce qui fonctionne bien. Voici un exemple de ce que je fais ( outputs est un cadre de données des cultures dont j'ai besoin, donc crop.grid est juste un vecteur de 4 nombres.

crop.grid <- c( outputs$x.start[x],
                outputs$y.start[x],
                outputs$x.stop[x],
                outputs$y.stop[x] )
crop.grid <- as.integer( crop.grid )
crop.grid <- reticulate::r_to_py( crop.grid )
output.array <- img$crop( box = crop.grid )
output.array$save( output.filename )

Après cela, je veux effacer l'image de la mémoire (les images que j'ouvre sont très grandes, donc prennent beaucoup de mémoire). J'essaie de fermer l'image en python :

img$close()

Ainsi qu'en R :

rm( img )
gc()

Et remplacer l'objet par quelque chose que je sais être très petit.

img <- reticulate::r_to_py( 1L )

Toutes ces choses fonctionnent bien, mais ma RAM est toujours enregistrée comme étant très pleine. Je les essaie avec chacun des objets python que j'ai créés, mais la seule chose qui vide efficacement la RAM est de redémarrer la session R.

Je sais que dans python Je ferais mieux d'ouvrir l'image en utilisant with afin de l'effacer à la fin du processus, mais je ne suis pas sûr de savoir comment mettre en œuvre cela en utilisant reticulate .


--- UPDATE avec une analogie python version :

Si je fais ce qui précède en python directement :

from PIL import Image
img = Image.open( "/home/user/Desktop/image.jpg" )
output = img.crop( [0,0,100,100] )

Et ensuite fermer les choses :

output.close()
img.close()

La mémoire s'efface. La même chose ne fonctionne pas à partir de R, par exemple :

output.array$close()
img$close()
gc() # for good measure

Ça n'efface pas la mémoire.

4voto

Nathan Werth Points 3469

Vous devez faire 3 choses :

  1. Créez explicitement l'objet en Python :

    py_env <- py_run_string(
        paste(
            "from PIL import Image",
            "img = Image.open('~/Desktop/image.jpg')",
            sep = "\n"
        ),
        convert = FALSE
    )
    img <- py_env$img
  2. Lorsque vous avez terminé avec l'image, supprimez d'abord l'objet Python.

    py_run_string("del img")
  3. Ensuite, lancez le collecteur de déchets Python.

    py_gc <- import("gc")
    py_gc$collect()

Les étapes 2 et 3 sont les plus importantes. L'étape 1 est juste pour que vous ayez un nom à supprimer. S'il existe un moyen de supprimer les objets Python "implicites" (je ne trouve pas de meilleur terme), cela permettrait d'économiser du texte standard.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X