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
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.
** reticulate ** peut être installé à partir du CRAN comme suit.
install.packages("reticulate")
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'argument
required` 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.
Emplacement spécifié en appelant ʻuse_python, ʻuse_virtualenv
, ʻuse_condaenv`
Emplacement spécifié par la variable d'environnement RETICULATE_PYTHON
L'emplacement de Python trouvé dans le PATH
du système (par la fonction Sys.which
)
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()
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).
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
.
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
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.
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.
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é
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)
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.
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. |
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. |
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. |
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. |
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:
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)
}
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
})
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