Dieses Dokument ist eine Vignette ["R-Schnittstelle zu Python"](https: //) des R-Pakets reticulate
(Version 0.7) von RStudio et al. Dies ist eine Übersetzung von cran.r-project.org/package=reticulate/vignettes/introduction.html).
License: Apache License 2.0
Das Paket ** reticulate ** bietet eine R-Schnittstelle zu Python-Modulen, -Klassen und -Funktionen. Der folgende Code importiert beispielsweise das Python-Modul "os" und ruft die darin enthaltenen Funktionen auf.
library(reticulate)
os <- import("os")
os$chdir("tests")
os$getcwd()
Auf Funktionen und andere Daten in Python-Modulen und -Klassen kann mit dem Operator $
zugegriffen werden (ähnlich wie beim Arbeiten mit R-Listen, Umgebungen und Referenzklassen).
Wenn Sie Python aufrufen, wird der R-Datentyp automatisch in das Python-Äquivalent konvertiert. Wenn ein Wert von Python an R zurückgegeben wird, wird er in den Typ R konvertiert. Der Typ wird wie folgt konvertiert.
R | Python | Beispiel |
---|---|---|
Ein Elementvektor | Skalar | 1 , 1L , TRUE , "foo" |
Mehrelementvektor | aufführen | c(1.0, 2.0, 3.0) , c(1L, 2L, 3L) |
Liste mit mehreren Typen | Taple | list(1L, TRUE, "foo") |
Benannte Liste | Wörterbuch | list(a = 1L, b = 2.0) , dict(x = x_data) |
Warteschlange/Array | NumPy-Array(ndarray) | matrix(c(1,2,3,4), nrow = 2, ncol = 2) |
Funktion | Python-Funktionen | function(x) x + 1 |
NULL, TRUE, FALSE | None, True, False | NULL , TRUE , FALSE |
Wenn ein benutzerdefiniertes Python-Objekt der Klasse zurückgegeben wird, gibt R einen Verweis auf dieses Objekt zurück. Für dieses Objekt können Sie Methoden aufrufen und auf Eigenschaften zugreifen, als wäre es eine Instanz der Referenzklasse von R.
Das Paket ** reticulate ** funktioniert mit allen Python-Versionen 2.7 und höher. Numpy kann optional integriert werden, Numpy 1.6 oder höher ist jedoch erforderlich.
** reticulate ** kann wie folgt von CRAN installiert werden.
install.packages("reticulate")
Wenn sich die Version von Python, die Sie verwenden möchten, im "PATH" Ihres Systems befindet, wird sie automatisch gefunden und verwendet (von "Sys.which").
Alternativ können Sie eine der folgenden Funktionen verwenden, um eine andere Version von Python anzugeben.
Funktion | Erläuterung |
---|---|
use_python | Geben Sie den Pfad zu einer bestimmten Python-Binärdatei an. |
use_virtualenv | Geben Sie das Verzeichnis an, das Python virtualenv enthält. |
use_condaenv | Geben Sie die Umgebung von conda an. |
Beispiel:
library(reticulate)
use_python("/usr/local/bin/python")
use_virtualenv("~/myenv")
use_condaenv("myenv")
Numpy 1.6 oder höher ist erforderlich, um die Funktionen von Numpy mit ** reticulate ** zu verwenden. Daher wird eine Version von Python bevorzugt, die diese Anforderung erfüllt.
Beachten Sie auch, dass die Funktionsfamilie use
standardmäßig nur ein Hinweis darauf ist, wo Python zu finden ist (dh, es tritt kein Fehler auf, wenn die angegebene Version von Python nicht vorhanden ist). Fügen Sie das Argument required
hinzu, um sicherzustellen, dass die angegebene Version von Python tatsächlich vorhanden ist.
use_virtualenv("~/myenv", required = TRUE)
Die Version von Python, die in der folgenden Reihenfolge gesucht und gefunden wird, wird verwendet.
Speicherort, der durch Aufrufen von "use_python", "use_virtualenv", "use_condaenv" angegeben wird
Speicherort, der durch die Umgebungsvariable RETICULATE_PYTHON
angegeben wird
Die Position von Python im PATH des Systems (durch die Funktion Sys.which)
Andere übliche Speicherorte für Python. / usr / local / bin / python
, / opt / local / bin / python
usw.
In einer typischen Verwendung wird die Python-Erkundung und -Bindung beim ersten Aufruf von "import" in einer R-Sitzung ausgeführt. Infolgedessen wird bevorzugt die Version von Python verwendet, die das im Aufruf "import" angegebene Modul enthält (dh die Version von Python, die das angegebene Modul nicht enthält, wird übersprungen).
Mit der Funktion py_config
können Sie Informationen zu Ihrer Python-Version und anderen auf Ihrem System gefundenen Python-Versionen abfragen.
py_config()
Sie können jedes Python-Modul mit der Funktion "Importieren" importieren. Zum Beispiel.
difflib <- import("difflib")
difflib$ndiff(foo, bar)
filecmp <- import("filecmp")
filecmp$cmp(dir1, dir2)
Mit den Funktionen import_main
und import_builtins
haben Sie Zugriff auf das Hauptmodul, in dem standardmäßig Code ausgeführt wird, und die integrierten Python-Funktionen. Zum Beispiel.
main <- import_main()
py <- import_builtins()
py$print('foo')
Im Allgemeinen ist das Hauptmodul nützlich, wenn Sie Python-Code aus einer Datei oder einem String ausführen und auf die Ergebnisse zugreifen möchten (weitere Informationen finden Sie im folgenden Abschnitt).
Wenn ein Python-Objekt an R zurückgegeben wird, wird es standardmäßig in den entsprechenden R-Typ konvertiert. Wenn Sie jedoch die Python-zu-R-Konvertierung explizit machen und die Standardeinstellung für die Verarbeitung nativer Python-Objekte festlegen möchten, können Sie "convert = FALSE" an die "import" -Funktion übergeben.
#Importiere numpy und verbiete die automatische Konvertierung von Python nach R.
np <- import("numpy", convert = FALSE)
#Bearbeiten Sie Arrays mit NumPy
a <- np$array(c(1:4))
sum <- a$cumsum()
#Schließlich explizit in R konvertieren
py_to_r(sum)
Wie oben gezeigt, können Sie die Funktion py_to_r
explizit aufrufen, wenn Sie am Ende der Berechnung Zugriff auf das R-Objekt benötigen.
Sie können Python-Code im Hauptmodul mit den Funktionen py_run_file
und py_run_string
ausführen. Beide Funktionen geben einen Verweis auf das Hauptmodul von Python zurück, sodass Sie auf die Ausführungsergebnisse zugreifen können. Zum Beispiel.
py_run_file("script.py")
main <- py_run_string("x = 10")
main$x
Die automatische Konvertierung vom R-Typ zum Python-Typ funktioniert in den meisten Fällen gut, in einigen Fällen ist jedoch eine explizitere Manipulation auf der R-Seite erforderlich, um den von der Python-Seite erwarteten Typ zu erhalten.
Wenn die Python-API beispielsweise eine Liste anfordert und Sie einen Vektor eines Elements von R übergeben, wird dieser in einen Python-Skalar konvertiert. Um dies zu überwinden, verwenden Sie einfach explizit die list
-Funktion von R.
foo$bar(indexes = list(42L))
In ähnlicher Weise erfordert die Python-API möglicherweise Tapples anstelle von Listen. In diesem Fall können Sie die Funktion "Tupel" verwenden.
tuple("a", "b", "c")
Obwohl die benannte Liste von R in ein Python-Wörterbuch konvertiert wird. Sie können ein Python-Wörterbuch auch explizit mit der Funktion dict
erstellen.
dict(foo = "bar", index = 42L)
Dies kann nützlich sein, wenn Sie ein Wörterbuch mit komplexeren Objekten (keine Zeichenfolgen) als Schlüssel übergeben müssen.
Sie können die generische Funktion with
von R verwenden, um Python-Kontextmanagerobjekte zu bearbeiten (in Python können Sie dasselbe mit dem Schlüsselwort with
tun). Zum Beispiel.
py <- import_builtins()
with(py$open("output.txt", "w") %as% file, {
file$write("Hello, there!")
})
In diesem Beispiel wird eine Datei geöffnet und garantiert, dass sie am Ende des with-Blocks automatisch geschlossen wird. Beachten Sie, dass wir den Operator "% as%" verwenden, um dem vom Kontextmanager erstellten Objekt einen Alias zu geben.
Wenn die Python-API [Iteratoren und Generatoren] zurückgibt (http://anandology.com/python-practice-book/iterators.html), können Sie dies mit der Funktion "iterieren" bearbeiten. .. Sie können die Funktion "iterieren" verwenden, um die R-Funktion auf jedes vom Iterator zurückgegebene Element anzuwenden.
iterate(iter, print)
Wenn Sie keine Funktion zum "Iterieren" übergeben, werden die Ergebnisse in einem R-Vektor gesammelt.
results <- iterate(iter)
Beachten Sie, dass die Funktion "iterieren" den Wert des Iterators verbraucht.
a <- iterate(iter) #Das Ergebnis ist nicht leer
b <- iterate(iter) #Das Ergebnis ist leer, da das Element bereits verbraucht wurde
Einige Python-Objekte können aufgerufen werden (dh sie können mit Argumenten wie gewöhnlichen Funktionen aufgerufen werden) sowie auf Methoden und Eigenschaften zugreifen. Aufrufbare Python-Objekte werden als Objekte und nicht als Funktionen an R zurückgegeben. Sie können aufrufbare Funktionen jedoch mit der Methode $ call ()
ausführen. Zum Beispiel.
#Rufen Sie ein aufrufbares Objekt ab
parser <- spacy$English()
#Rufen Sie ein Objekt als Funktion auf
parser$call(spacy)
Es stehen auch erweiterte Funktionen zur Verfügung, die vor allem beim Erstellen von R-Schnittstellen auf hoher Ebene für Python-Bibliotheken hilfreich sind.
Um mit Python-Objekten aus R zu arbeiten, verwenden Sie normalerweise den Operator $
, um auf die erforderliche Objektfunktionalität zuzugreifen. Mit $
werden Python-Objekte nach Möglichkeit automatisch in R-Äquivalente konvertiert. Die folgenden Funktionen können jedoch verwendet werden, um Python-Objekte auf einer niedrigeren Ebene (z. B. explizit) zu bearbeiten. Wenn Sie nicht py_to_r
aufrufen, wird R nicht in ein Objekt konvertiert.
Funktion | Erläuterung |
---|---|
py_has_attr | Überprüfen Sie, ob das Objekt die angegebenen Attribute hat. |
py_get_attr | Ruft die Attribute eines Python-Objekts ab. |
py_set_attr | Legen Sie die Attribute des Python-Objekts fest. |
py_list_attributes | Ruft eine Liste aller Attribute eines Python-Objekts ab. |
py_call | Ruft ein aufrufbares Python-Objekt mit dem angegebenen Argument auf. |
py_to_r | Konvertieren Sie ein Python-Objekt in ein R-Äquivalent. |
r_to_py | Konvertieren Sie ein R-Objekt in ein Python-Äquivalent. |
Mit den folgenden Funktionen können Sie Informationen zu den auf Ihrem aktuellen System verfügbaren Python-Einstellungen abfragen.
Funktion | Erläuterung |
---|---|
py_available | Überprüfen Sie, ob die Schnittstelle zu Python auf diesem System verfügbar ist. |
py_numpy_available | Überprüfen Sie, ob die R-Schnittstelle zu NumPy verfügbar ist (NumPy 1 erforderlich)..6 oder mehr). |
py_module_available | Überprüfen Sie, ob Python-Module auf diesem System verfügbar sind. |
py_config | Informieren Sie sich über den Speicherort und die Version von Python. |
Mit den folgenden Funktionen können Sie die Ausgabe von Python erfassen oder unterdrücken.
Funktion | Erläuterung |
---|---|
py_capture_output | Erfasst die Python-Ausgabe für den angegebenen Ausdruck und gibt sie als R-Zeichenvektor zurück. |
py_suppress_warnings | Führt den angegebenen Ausdruck aus, unterdrückt jedoch die Anzeige von Python-Warnungen. |
Die folgenden Funktionen bieten eine Vielzahl anderer Funktionen auf niedriger Ebene.
Funktion | Erläuterung |
---|---|
py_unicode | Konvertieren Sie eine Zeichenfolge in ein Python-Unicode-Objekt. |
py_str | Ruft die Zeichenfolgendarstellung eines Python-Objekts ab. |
py_is_null_xptr | Überprüfen Sie, ob das Python-Objekt ein Null-Externalptr ist. |
py_validate_xptr | Überprüfen Sie, ob das Python-Objekt ein Null-Externalptr ist, und geben Sie in diesem Fall einen Fehler aus. |
Wenn Sie ** reticulate ** mit anderen R-Paketen verwenden möchten, müssen Sie Folgendes berücksichtigen: Wenn ein Paket an CRAN gesendet wird, verfügt der CRAN-Testserver möglicherweise nicht über Python, NumPy oder ein anderes Python-Modul, das Sie in das Paket einbinden möchten.
Um sicherzustellen, dass Ihr Paket gut mit CRAN funktioniert, sollten Sie zwei Dinge tun:
Wenn Sie Python-Module zur Verwendung in einem Paket importieren, sollten Sie die Option delay_load
verwenden, um sicherzustellen, dass die Module (und Python) nur bei der ersten Verwendung geladen werden.
#Von Python möchten Sie in Ihrem Paket verwenden'foo'Modul
foo <- NULL
.onLoad <- function(libname, pkgname) {
#Faules Laden des foo-Moduls ($Wird nur beim Zugriff mit geladen)
foo <<- import("foo", delay_load = TRUE)
}
Überprüfen Sie beim Schreiben eines Tests, ob das Modul verfügbar ist, und überspringen Sie den Test, wenn es nicht verfügbar ist. Wenn Sie beispielsweise das Paket ** testthat ** verwenden, sieht es folgendermaßen aus:
# 'foo'Hilfsfunktion zum Überspringen von Tests, wenn kein Modul vorhanden ist
skip_if_no_foo <- function() {
have_foo <- py_module_available("foo")
if (!have_foo)
skip("Foo steht nicht zum Testen zur Verfügung!")
}
#Rufen Sie diese Hilfsfunktion in allen Tests auf
test_that("Funktioniert wie erwartet", {
skip_if_no_foo()
#Schreiben Sie hier den Testcode
})
Da die Klasse des Python-Objekts, das auf der R-Seite verfügbar gemacht wird, durch ** reticulate ** auf R übertragen wird, ist es möglich, eine S3-Methode für die Klasse zu schreiben und beispielsweise das Verhalten von str
und print
anzupassen. Sie können (müssen aber normalerweise nicht), da die Standardmethoden "str" und "print" "PyObject_Str" aufrufen, was normalerweise ein akzeptables Standardverhalten bietet.
Wenn Sie sich wirklich dazu entschließen, eine angepasste S3-Methode für Ihre Python-Klasse zu implementieren, ist Folgendes zu beachten: Das heißt, die Verbindung zum Python-Objekt wird am Ende der R-Sitzung unterbrochen, sodass beim Wiederherstellen von .RData, die in einer R-Sitzung in einer nachfolgenden R-Sitzung gespeichert wurden, das Python-Objekt (genau) effektiv verloren geht. Mit anderen Worten, es wird ein NULL`` externalptr
Objekt von R).
Dies bedeutet, dass Sie immer "py_is_null_xptr" verwenden sollten, bevor Sie Python-Objekte mit S3-Methoden bearbeiten. Zum Beispiel.
#' @export
summary.MyPythonClass <- function(object, ...) {
if (py_is_null_xptr(object))
stop("Object is NULL")
else
#Bearbeiten Sie Objekte, um Zusammenfassungen zu erstellen
}
Um dies zu vereinfachen, stehen einige Verknüpfungsmethoden zur Verfügung. Die Funktion py_validate_xptr
führt die erforderlichen Überprüfungen durch und gibt automatisch einen Fehler aus, wenn dies fehlschlägt. Das obige Beispiel könnte also wie folgt umgeschrieben werden:
#' @export
summary.MyPythonClass <- function(object, ...) {
py_validate_xptr(object)
#Bearbeiten Sie Objekte, um Zusammenfassungen zu erstellen
}
Schließlich exportiert das Paket ** reticulate ** die generische Funktion py_str
, die eine ordnungsgemäße Validierung von der Methode str
zurückgibt (gibt<Zeiger: 0x0>
zurück, wenn das Objekt NULL ist). Es wird erst nach Durchlaufen von [^ tr1] aufgerufen. Sie können die Methode "py_str" wie folgt implementieren.
#' @importFrom reticulate py_str
#' @export
py_str.MyPythonClass <- function(object, ...) {
#Bearbeiten Sie Objekte, um Zeichenfolgen zu generieren
}
Kurz gesagt, implementieren Sie "py_str", um benutzerdefinierte "str" - und "print" -Methoden bereitzustellen. Rufen Sie bei anderen S3-Methoden unbedingt "py_validate_xptr" oder "py_is_null_xptr" auf, bevor Sie das Objekt bearbeiten.
[^ tr1]: Ich finde es etwas verwirrend, also werde ich es hinzufügen. Zunächst wird durch Retikulieren jedes Python-Objekt auf der R-Seite als Objekt angezeigt, das die Klasse python.builtin.object
erbt. Eine "str" -Methode ist für "python.builtin.object" definiert, und diese Methode ruft die generische Funktion "py_str" auf. Und die generische Funktion py_str
hat eine Struktur, die die Methode nach Überprüfung des Arguments aufruft.
```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