[Übersetzung] Vignette retikulieren: R zu Python-Schnittstelle

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


Überblick

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.

Installation

** reticulate ** kann wie folgt von CRAN installiert werden.

install.packages("reticulate")

Identifizieren des Speicherorts von Python

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.

  1. Speicherort, der durch Aufrufen von "use_python", "use_virtualenv", "use_condaenv" angegeben wird

  2. Speicherort, der durch die Umgebungsvariable RETICULATE_PYTHON angegeben wird

  3. Die Position von Python im PATH des Systems (durch die Funktion Sys.which)

  4. 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()

Modulimport

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).

Objektkonvertierung

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.

Codeausführung

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

Listen, Taples, Wörterbücher

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.

Kontext

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.

Iterator

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

Aufrufbares Objekt

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)

Erweiterte Funktionen

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.

Python-Objekt

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.

Aufbau

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.

Ausgabesteuerung

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.

Andere

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.

Verwendung in Verpackungen

Überprüfen und testen Sie mit CRAN

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:

  1. 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)
    }
    
  1. Ü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
    })
    

S3-Methode

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

[Übersetzung] Vignette retikulieren: R zu Python-Schnittstelle
So machen Sie R chartr () in Python
Auf Python 2.7.9 aktualisiert
"Backport" zu Python 2
Ich möchte R-Datensatz mit Python verwenden
So installieren Sie Python
Änderungen von Python 3.0 zu Python 3.5
Änderungen von Python 2 zu Python 3.0
Schreiben Sie Python2-Code in Python3 um (2to3)
So installieren Sie Python
Einführung in die Python-Sprache
Einführung in OpenCV (Python) - (2)
[Übersetzung] 25 Jahre alter Python
Beachten Sie, dass Python ein Daemon ist
Einführung von Python 2.7 in CentOS 6.6
Verbinden Sie Python mit MySQL
[R] [Python] Memo zum Lesen mehrerer CSV-Dateien in mehreren Zip-Dateien
Erstellen Sie eine Nachricht, die der Lokalisierung entspricht, mit einer Python-Übersetzungszeichenfolge
(Übersetzung) Native Verbindung von Python zum Hadoop-Dateisystem (HDFS)