[Français] vignette réticulée: interface R vers Python

Ce document est une vignette ["R interface to Python"](https: //) du package R reticulate (Version 0.7) par RStudio et al. Ceci est une traduction de cran.r-project.org/package=reticulate/vignettes/introduction.html).

License: Apache License 2.0


Aperçu

Le package ** reticulate ** fournit une interface R aux modules, classes et fonctions Python. Par exemple, le code suivant importe le module Python ʻos` et y appelle les fonctions.

library(reticulate)
os <- import("os")
os$chdir("tests")
os$getcwd()

Les fonctions et autres données des modules et classes Python sont accessibles avec l'opérateur $ (similaire à l'utilisation de listes R, d'environnements et de classes de référence).

Lorsque vous appelez Python, le type de données R est automatiquement converti en équivalent Python. Lorsqu'une valeur est renvoyée de Python à R, elle est convertie en type R. Le type est converti comme suit.

R Python Exemple
Un vecteur d'élément scalaire 1, 1L, TRUE, "foo"
Vecteur multi-éléments liste c(1.0, 2.0, 3.0), c(1L, 2L, 3L)
Liste contenant plusieurs types Taple list(1L, TRUE, "foo")
Liste nommée dictionnaire list(a = 1L, b = 2.0), dict(x = x_data)
queue/Tableau Tableau NumPy(ndarray) matrix(c(1,2,3,4), nrow = 2, ncol = 2)
une fonction Fonctions Python function(x) x + 1
NULL, TRUE, FALSE None, True, False NULL, TRUE, FALSE

Si un objet Python de classe personnalisée est renvoyé, R renverra une référence à cet objet. Pour cet objet, vous pouvez appeler des méthodes et accéder aux propriétés comme s'il s'agissait d'une instance de la classe de référence de R.

Le package ** reticulate ** fonctionne avec toutes les versions 2.7 et supérieures de Python. Numpy peut être intégré en option, mais Numpy 1.6 ou supérieur est requis.

Installation

** reticulate ** peut être installé à partir du CRAN comme suit.

install.packages("reticulate")

Identifier l'emplacement de Python

Si la version de Python que vous souhaitez utiliser se trouve dans le PATH de votre système, elle sera automatiquement trouvée et utilisée (par Sys.which).

Vous pouvez également utiliser l'une des fonctions suivantes pour spécifier une autre version de Python.

une fonction La description
use_python Spécifiez le chemin vers un binaire Python spécifique.
use_virtualenv Spécifiez le répertoire qui contient le virtualenv Python.
use_condaenv Spécifiez l'environnement de conda.

Exemple:

library(reticulate)
use_python("/usr/local/bin/python")
use_virtualenv("~/myenv")
use_condaenv("myenv")

Numpy 1.6 ou supérieur est requis pour utiliser les fonctionnalités de Numpy avec ** reticulate **, donc une version de Python qui répond à cette exigence est préférée.

Notez également que par défaut, la famille de fonctions ʻuseest juste une indication de l'endroit où Python peut être trouvé (c'est-à-dire qu'aucune erreur ne se produira si la version spécifiée de Python n'existe pas). Ajoutez l'argumentrequired` pour vous assurer que la version spécifiée de Python existe réellement.

use_virtualenv("~/myenv", required = TRUE)

La version de Python recherchée et trouvée dans l'ordre suivant est utilisée.

  1. Emplacement spécifié en appelant ʻuse_python, ʻuse_virtualenv, ʻuse_condaenv`

  2. Emplacement spécifié par la variable d'environnement RETICULATE_PYTHON

  3. L'emplacement de Python trouvé dans le PATH du système (par la fonction Sys.which)

  4. Autres emplacements habituels pour Python. / usr / local / bin / python, / opt / local / bin / python, etc.

Dans une utilisation typique, l'exploration et la liaison Python sont effectuées la première fois que vous appelez ʻimport dans une session R. En conséquence, la version de Python qui contient le module spécifié dans l'appel à ʻimport est préférentiellement utilisée (c'est-à-dire que la version de Python qui ne contient pas le module spécifié est ignorée).

Vous pouvez utiliser la fonction py_config pour demander des informations sur votre version de Python ou sur toute autre version de Python que vous pouvez trouver sur votre système.

py_config()

Importation de module

Vous pouvez importer n'importe quel module Python en utilisant la fonction ʻimport`. Par exemple.

difflib <- import("difflib")
difflib$ndiff(foo, bar)

filecmp <- import("filecmp")
filecmp$cmp(dir1, dir2)

Les fonctions ʻimport_main et ʻimport_builtins vous donnent accès au module principal, où le code est exécuté par défaut, et aux fonctions Python intégrées. Par exemple.

main <- import_main()

py <- import_builtins()
py$print('foo')

En général, le module principal est utile lorsque vous souhaitez exécuter du code Python à partir d'un fichier ou d'une chaîne et accéder aux résultats (voir la section ci-dessous pour plus de détails).

Conversion d'objets

Lorsqu'un objet Python est renvoyé à R, il est converti par défaut en type équivalent R. Cependant, si vous voulez rendre explicite la conversion Python vers R et en faire le paramètre par défaut pour gérer les objets Python natifs, vous pouvez passer convert = FALSE à la fonction ʻimport`.

#Importez numpy et interdisez la conversion automatique de Python vers R
np <- import("numpy", convert = FALSE)

#Manipuler des tableaux avec NumPy
a <- np$array(c(1:4))
sum <- a$cumsum()

#Enfin convertir explicitement en R
py_to_r(sum)

Comme indiqué ci-dessus, si vous avez besoin d'accéder à l'objet R à la fin du calcul, vous pouvez appeler explicitement la fonction py_to_r.

Exécution du code

Vous pouvez exécuter du code Python dans le module principal en utilisant les fonctions py_run_file et py_run_string. Ces deux fonctions renvoient une référence au module principal de Python, afin que vous puissiez accéder aux résultats de l'exécution. Par exemple.

py_run_file("script.py")

main <- py_run_string("x = 10")
main$x

Listes, taples, dictionnaires

La conversion automatique du type R au type Python fonctionne bien dans la plupart des cas, mais dans certains cas, une manipulation plus explicite est nécessaire du côté R pour donner le type attendu par Python.

Par exemple, si l'API Python demande une liste et que vous transmettez un vecteur d'un élément de R, il sera converti en un scalaire Python. Pour surmonter cela, utilisez simplement la fonction list de R explicitement.

foo$bar(indexes = list(42L))

De même, l'API Python peut nécessiter des tapples au lieu de listes, auquel cas vous pouvez utiliser la fonction tuple.

tuple("a", "b", "c")

Bien que la liste nommée de R soit convertie en dictionnaire Python. Vous pouvez également créer explicitement un dictionnaire Python en utilisant la fonction dict.

dict(foo = "bar", index = 42L)

Cela peut être utile si vous devez passer un dictionnaire avec des objets plus complexes (pas des chaînes) comme clés.

le contexte

Vous pouvez utiliser la fonction générique with de R pour manipuler les objets du gestionnaire de contexte Python (en Python, vous pouvez faire de même avec le mot clé with). Par exemple.

py <- import_builtins()
with(py$open("output.txt", "w") %as% file, {
  file$write("Hello, there!")
})

Cet exemple ouvre un fichier et garantit qu'il sera fermé automatiquement à la fin du bloc with. Notez que nous utilisons l'opérateur % as% pour donner un alias à l'objet créé par le gestionnaire de contexte.

Itérateur

Si l'API Python renvoie itérateurs et générateurs, vous pouvez manipuler cela en utilisant la fonction ʻiterate. .. Vous pouvez utiliser la fonction ʻiterate pour appliquer la fonction R à chaque élément renvoyé par l'itérateur.

iterate(iter, print)

Si vous ne passez pas une fonction à «écrire», les résultats seront rassemblés dans un vecteur R.

results <- iterate(iter)

Notez que la valeur de l'itérateur est consommée par la fonction ʻiterate`.

a <- iterate(iter) #Le résultat n'est pas vide
b <- iterate(iter) #Le résultat est vide car l'élément a déjà été consommé

Objet appelable

Certains objets Python peuvent être appelés (c'est-à-dire qu'ils peuvent être appelés avec des arguments comme des fonctions ordinaires), ainsi que l'accès aux méthodes et propriétés. Les objets Python appelables sont retournés à R comme des objets plutôt que des fonctions, mais vous pouvez exécuter des fonctions appelables avec la méthode $ call (). Par exemple.

#Obtenir un objet appelable
parser <- spacy$English()
#Appeler un objet en tant que fonction
parser$call(spacy)

Fonctions avancées

Des fonctions plus avancées sont également disponibles, qui sont principalement utiles lors de la création d'interfaces R de haut niveau pour les bibliothèques Python.

Objet Python

Pour travailler avec des objets Python de R, vous utilisez généralement l'opérateur $ pour accéder à la fonctionnalité d'objet requise. Avec «$», les objets Python sont automatiquement convertis en équivalents R si possible, mais les fonctions suivantes peuvent être utilisées pour manipuler des objets Python à un niveau inférieur (par exemple, explicite). Sauf si vous appelez py_to_r, R ne sera pas converti en objet).

une fonction La description
py_has_attr Vérifiez si l'objet possède les attributs spécifiés.
py_get_attr Obtenez les attributs d'un objet Python.
py_set_attr Définissez les attributs de l'objet Python.
py_list_attributes Obtenez une liste de tous les attributs d'un objet Python.
py_call Appelle un objet appelable Python avec l'argument spécifié.
py_to_r Convertissez un objet Python en un équivalent R.
r_to_py Convertissez un objet R en un équivalent Python.

Réglage

Vous pouvez utiliser les fonctions suivantes pour rechercher des informations sur les paramètres Python disponibles sur votre système actuel.

une fonction La description
py_available Vérifiez si l'interface vers Python est disponible sur ce système.
py_numpy_available Vérifiez si l'interface R vers NumPy est disponible (NumPy 1 requis).6 ou plus).
py_module_available Vérifiez si les modules Python sont disponibles sur ce système.
py_config Obtenez des informations sur l'emplacement et la version de Python en cours d'utilisation.

Contrôle de sortie

Vous pouvez utiliser les fonctions suivantes pour capturer ou supprimer la sortie de Python.

une fonction La description
py_capture_output Capture la sortie Python pour l'expression spécifiée et la renvoie sous la forme d'un vecteur de caractères R.
py_suppress_warnings Exécute l'expression spécifiée, mais supprime l'affichage des avertissements Python.

Autre

Les fonctions suivantes fournissent une variété d'autres fonctionnalités de bas niveau.

une fonction La description
py_unicode Convertit une chaîne en un objet Python Unicode.
py_str Obtenez la représentation sous forme de chaîne d'un objet Python.
py_is_null_xptr Vérifiez si l'objet Python est un externalptr nul.
py_validate_xptr Vérifiez si l'objet Python est un externalptr nul et lancez une erreur si c'est le cas.

Utilisation dans l'emballage

Vérifier et tester avec CRAN

Si vous souhaitez utiliser ** reticulate ** avec d'autres packages R, vous devez tenir compte des éléments suivants: Autrement dit, lorsqu'un package est soumis à CRAN, le serveur de test de CRAN peut ne pas avoir Python, NumPy ou tout autre module Python que vous essayez d'encapsuler dans le package.

Pour vous assurer que votre package fonctionne bien avec CRAN, vous devez faire deux choses:

  1. Lors de l'importation de modules Python à utiliser dans un package, vous devez utiliser l'option delay_load pour vous assurer que les modules (et Python) ne sont chargés que la première fois qu'ils sont utilisés.

    #De python que vous souhaitez utiliser dans votre package'foo'module
    foo <- NULL
    
    .onLoad <- function(libname, pkgname) {
      #Chargement paresseux du module foo ($Chargé uniquement lors de l'accès avec)
      foo <<- import("foo", delay_load = TRUE)
    }
    
  1. Lors de l'écriture d'un test, vérifiez si le module est disponible et ignorez le test s'il n'est pas disponible. Par exemple, si vous utilisez le package ** testthat **, cela ressemblerait à ceci:

    # 'foo'Fonction d'aide pour sauter les tests s'il n'y a pas de module
    skip_if_no_foo <- function() {
      have_foo <- py_module_available("foo")
      if (!have_foo)
        skip("Foo n'est pas disponible pour les tests!")
    }
    
    #Appelez cette fonction d'assistance dans tous les tests
    test_that("Fonctionne comme prévu", {
      skip_if_no_foo()
      #Écrivez le code de test ici
    })
    

Méthode S3

Puisque la classe de l'objet Python exposée sur le côté R est reportée sur R par ** reticulate **, il est possible d'écrire une méthode S3 pour la classe et de personnaliser le comportement de str et print, par exemple. Vous pouvez (mais généralement pas besoin), parce que les méthodes par défaut str et print appellent PyObject_Str, ce qui fournit généralement un comportement par défaut acceptable.

Si vous décidez vraiment d'implémenter une méthode S3 personnalisée pour votre classe Python, il est important de garder à l'esprit les points suivants: Autrement dit, la connexion à l'objet Python est perdue à la fin de la session R, donc la restauration de .RData enregistrée dans une session R dans une session R ultérieure perd effectivement l'objet Python (exactement). En d'autres termes, il devient un objet ʻexternalptr NULL de R).

Cela signifie que vous devez toujours utiliser py_is_null_xptr avant de manipuler des objets Python avec des méthodes S3. Par exemple.

#' @export
summary.MyPythonClass <- function(object, ...) {
  if (py_is_null_xptr(object))
    stop("Object is NULL")
  else
    #Manipulez des objets pour générer des résumés
}

Pour vous faciliter la tâche, certaines méthodes de raccourcis sont disponibles. La fonction py_validate_xptr effectue les vérifications nécessaires et renvoie automatiquement une erreur en cas d'échec. Ainsi, l'exemple ci-dessus pourrait être réécrit comme suit:

#' @export
summary.MyPythonClass <- function(object, ...) {
  py_validate_xptr(object)
  #Manipulez des objets pour générer des résumés
}

Enfin, le package ** reticulate ** exporte la fonction générique py_str, qui renvoie une validation correcte de la méthode str (retourne<pointer: 0x0>si l'objet est NULL). Il n'est appelé qu'après avoir traversé [^ tr1]. Vous pouvez implémenter la méthode py_str comme suit.

#' @importFrom reticulate py_str
#' @export 
py_str.MyPythonClass <- function(object, ...) {
  #Manipuler des objets pour générer des chaînes
}

En bref, implémentez py_str pour fournir des méthodes personnalisées str et print. Pour les autres méthodes S3, assurez-vous d'appeler py_validate_xptr ou py_is_null_xptr avant de manipuler l'objet.

[^ tr1]: Je pense que c'est un peu déroutant, alors je vais l'ajouter. Tout d'abord, par réticulation, tout objet Python apparaît du côté R comme un objet qui hérite de la classe python.builtin.object. Une méthode str est définie pour python.builtin.object, et cette méthode appelle la fonction générique py_str. Et la fonction générique py_str a une structure qui appelle la méthode après avoir vérifié l'argument.

```r
reticulate:::str.python.builtin.object
```

```
## function (object, ...) 
## {
##     cat(py_str(object), "\n", sep = "")
## }
## <environment: namespace:reticulate>
```

```r
reticulate::py_str
```

```
## function (object, ...) 
## {
##     if (!inherits(object, "python.builtin.object")) 
##         py_str.default(object)
##     else if (py_is_null_xptr(object) || !py_available()) 
##         "<pointer: 0x0>"
##     else UseMethod("py_str")
## }
## <environment: namespace:reticulate>
```

Recommended Posts

[Français] vignette réticulée: interface R vers Python
Comment faire R chartr () en Python
Mis à jour vers Python 2.7.9
"Backport" vers python 2
Je veux utiliser le jeu de données R avec python
Comment installer Python
Changements de Python 3.0 à Python 3.5
Changements de Python 2 à Python 3.0
Réécrire le code Python2 en Python3 (2to3)
Comment installer python
Introduction au langage Python
Introduction à OpenCV (python) - (2)
[Français] Python de 25 ans
Remarque pour faire de python un démon
Introduction de Python 2.7 à CentOS 6.6
Connectez python à mysql
[R] [Python] Memo pour lire plusieurs fichiers csv dans plusieurs fichiers zip
Créer un message correspondant à la localisation avec la chaîne de traduction python
(Traduction) Connexion native de Python au système de fichiers Hadoop (HDFS)