Untersuchen Sie den Java- und Python-Datenaustausch mit Apache Arrow

Dieses Mal habe ich Apache Arrow verwendet, um den Datenaustausch zwischen Java und Python zu untersuchen.

Einführung

Es wird erwartet, dass der Datenaustausch mit Apache Arrow zwischen Systemen und Sprachen kopiert werden kann, ohne in den Speicher zu kopieren. Um die Schlussfolgerung zuerst zu schreiben, wurde sie in dieser Untersuchung über ein Byte-Array im Apache Arrow-Format ausgetauscht. Sie müssen es nicht auf Ihre lokale Festplatte schreiben, aber die Java-Serialisierung und die Python-Deserialisierung führen zum Kopieren von Daten im Speicher. Ich denke, der Vorteil der diesmal eingeführten Methode ist, dass es einfach ist, zwischen Sprachen zu verknüpfen, da es ein allgemeines Hochgeschwindigkeitsformat namens Apache Arrow gibt.

Informationen zum Austausch von Java- und Python-Daten mit Apache Arrow

Apache Arrow hatte eine Bibliothek namens jvm für den Datenaustausch zwischen Java und Python.

def record_batch(jvm_vector_schema_root):
    """
    Construct a (Python) RecordBatch from a JVM VectorSchemaRoot
    Parameters
    ----------
    jvm_vector_schema_root : org.apache.arrow.vector.VectorSchemaRoot
    Returns
    -------
    record_batch: pyarrow.RecordBatch
    """

image.png

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>gtest</groupId>
  <artifactId>gtest</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>gtest</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.arrow</groupId>
      <artifactId>arrow-vector</artifactId>
      <version>0.12.0</version>
    </dependency>
    <dependency>
      <groupId>net.sf.py4j</groupId>
      <artifactId>py4j</artifactId>
      <version>0.10.8.1</version>
    </dependency>
  </dependencies>

</project>
$ mvn dependency:copy-dependencies -DoutputDirectory=./lib -f ./pom.xml

Daher wird davon ausgegangen, dass der Datenaustausch zwischen Java und Python mithilfe von py4j problemlos durchgeführt werden kann. Holen Sie sich die Gläser, die Sie benötigen, um py4j zu verwenden. Der folgende Pom bringt die Pfeil- und Py4J-Gläser lokal. Der Befehl maven lautet wie folgt. Probieren Sie die JVM-Bibliothek aus

Erstellen Sie eine einfache Java-Klasse, indem Sie sich auf das Beispiel py4j beziehen. Es implementiert auch eine Funktion, die VecotrSchemaRoot zur Validierung auf py4j zurückgibt.

import java.util.List;
import java.util.ArrayList;

import py4j.GatewayServer;

import org.apache.arrow.memory.RootAllocator;
import org.apache.arrow.vector.BitVector;
import org.apache.arrow.vector.VectorSchemaRoot;

public class Py4jExample {

  public static void main( final String[] args ) {
    Py4jExample app = new Py4jExample();
    GatewayServer server = new GatewayServer( app );
    server.start();
  }

  /**
   *Bereiten Sie eine Funktion vor, um einen VectorSchemaRoot zum Ausprobieren zu erstellen.
   */
  public static VectorSchemaRoot create() {
    RootAllocator allocator = new RootAllocator( Integer.MAX_VALUE );
    BitVector vector = new BitVector( "test" , allocator );
    vector.allocateNew( 1 );
    vector.setSafe( 0 , 1 );
    vector.setValueCount( 1 );

    List list = new ArrayList();
    list.add( vector );

    VectorSchemaRoot root = new VectorSchemaRoot( list );
    root.setRowCount( 1 );

    return root;
  }

}

Kompilieren und starten.

$ javac -cp lib/*:. Py4jExample.java
$ java -cp lib/*:. Py4jExample &

Nachdem wir nun bereit sind, von Python aus aufzurufen, schreiben wir den Python-Prozess.

from py4j.java_gateway import JavaGateway
import pyarrow as pa
import pyarrow.jvm as j
from pyarrow import RecordBatch

gateway = JavaGateway()

root = gateway.jvm.Py4jExample.create()
rb = j.record_batch( root )

df = rb.to_pandas()

Ich dachte, es wäre einfach, mit der folgenden JVM-Bibliothek von Java in Pythons record_batch zu konvertieren ...

$ python test.py
Segmentation fault

Sie können es bis zu dem Punkt ausführen, an dem Sie RecordBatch erhalten, aber es scheint abzustürzen, wenn Sie to_pandas () aufrufen. Ich kann nicht sagen, ob meine Umgebung schlecht war, aber ich schien es nicht sofort zu verstehen, also beschloss ich, diesmal aufzugeben.

Datenaustausch im Byte-Array von Apache Arrow

Alternativ implementiert Apache Arrow auch ein Binärformat für die Datei, sodass sie von Java und Python in einem Byte-Array gelesen und geschrieben werden kann. Mit Blick auf die aktuelle (Stand 03.03.2019) Python-JVM-Implementierung schien sie beim Empfang eines Java-Objekts und beim Konvertieren in ein Python-Objekt im Speicher zu kopieren. Daher erfordert der Datenaustausch mit Byte-Arrays eine Serialisierung und Deserialisierung, aber nur die Serialisierung mit Byte-Arrays in Java ist kostspielig.

Java- und Python-Datenaustausch in Byte-Arrays

Fügen Sie der Java-Klasse eine Funktion hinzu, die ein Byte-Array erstellt.

  /**
   *Bereiten Sie eine Funktion vor, um ein Byte-Array von Arrow zu erstellen.
   */
  public static byte[] createArrowFile() throws IOException {
    RootAllocator allocator = new RootAllocator( Integer.MAX_VALUE );
    BitVector vector = new BitVector( "test" , allocator );
    vector.allocateNew( 1 );
    vector.setSafe( 0 , 1 );
    vector.setValueCount( 1 );

    List list = new ArrayList();
    list.add( vector );

    VectorSchemaRoot root = new VectorSchemaRoot( list );
    root.setRowCount( 1 );

    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ArrowFileWriter writer = new ArrowFileWriter( root, null, Channels.newChannel( out ) );
    writer.start();
    writer.writeBatch();
    writer.end();
    writer.close();
    return out.toByteArray();
  }

Kompilieren Sie diese Klasse und starten Sie sie erneut. Die Verarbeitung in Python wird geändert, um RecordBatch aus dem Byte-Array abzurufen.

from py4j.java_gateway import JavaGateway
import pyarrow as pa
import pyarrow.jvm as j
from pyarrow import RecordBatch

gateway = JavaGateway()

reader = pa.RecordBatchFileReader( pa.BufferReader( gateway.jvm.Py4jExample.createArrowFile() ) )
rb = reader.get_record_batch(0);

df = rb.to_pandas()

print df

Wie erwartet konnte ich VectorSchemaRoot, das in Java erstellt wurde, als RecordBatch in Python verarbeiten.

 $ python test2.py
   test
0  True

Zusammenfassung

Der Datenaustausch zwischen Java und Python ist mittlerweile zu einer Brute-Force-Implementierung geworden. Apache Arrow hat jedoch den Vorteil, dass es mit Bibliotheken kompatibel ist, die Daten mit Python wie Pandas verarbeiten, und dass Sie keine eigene Serialisierung und Deserialisierung implementieren müssen.

Der Zweck dieser Forschung war es, das derzeit entwickelte Dateiformat in Java zu implementieren und auch in Python verfügbar zu machen, das üblicherweise in der Datenverarbeitung verwendet wird. Basierend auf dieser Forschung möchte ich das nächste Mal ein Implementierungs- und Operationsbeispiel für das Lesen und Schreiben von Python in ein Dateiformat mit einem Byte-Array schreiben.

Recommended Posts

Untersuchen Sie den Java- und Python-Datenaustausch mit Apache Arrow
Datenpipeline-Aufbau mit Python und Luigi
CentOS 6.4, Python 2.7.3, Apache, mod_wsgi, Django
Kommunikation verschlüsselter Daten zwischen Python und C #
Datenanalyse mit Python 2
Datenanalyse mit Python
C-Sprache, Java, Python-Benchmarks mit Primfaktorisierung
Mit Python erstellte Beispieldaten
Programmieren mit Python und Tkinter
Ver- und Entschlüsselung mit Python
Python und Hardware-Verwenden von RS232C mit Python-
Apache mod_auth_tkt und Python AuthTkt
Holen Sie sich Youtube-Daten mit Python
Ich habe Java und Python verglichen!
Python mit Pyenv und Venv
Funktioniert mit Python und R.
Lesen von JSON-Daten mit Python
Word Count mit Apache Spark und Python (Mac OS X)
Befreien Sie sich mit Python und regulären Ausdrücken von schmutzigen Daten
Lösen mit Ruby, Perl, Java und Python AtCoder ATC 002 A.
Löse das Spiralbuch (Algorithmus und Datenstruktur) mit Python!
Lösen mit Ruby, Perl, Java und Python AtCoder ATC 002 B.
Holen Sie sich zusätzliche Daten zu LDAP mit Python (Writer und Reader)
Kommunizieren Sie mit FX-5204PS mit Python und PyUSB
Leuchtendes Leben mit Python und OpenCV
Unterschied zwischen Java und Python (Memo)
Roboter läuft mit Arduino und Python
Installieren Sie Python 2.7.9 und Python 3.4.x mit pip.
Vergleich der grundlegenden Grammatik zwischen Java und Python
Neuronales Netzwerk mit OpenCV 3 und Python 3
AM-Modulation und Demodulation mit Python
Machen Sie Apache Log CSV mit Python
Scraping mit Node, Ruby und Python
Scraping mit Python, Selen und Chromedriver
Kratzen mit Python und schöner Suppe
[Python] Mit DataReader Wirtschaftsdaten abrufen
Holen Sie sich Daten von VPS MySQL mit Python 3 und SQL Alchemy
JSON-Codierung und -Decodierung mit Python
[GUI in Python] PyQt5-Drag & Drop-
Python-Datenstruktur mit Chemoinfomatik gelernt
Hashing von Daten in R und Python
Lesen und Schreiben von NetCDF mit Python
Ich habe mit PyQt5 und Python3 gespielt
AtCoder ARC104 B Kumulative Summe in Ruby, Python und Java gelöst
Listen Sie Split- und Join-Zeichenfolgen mit Split und Join auf (Perl / PowerShell / Java / Kotlin / Python).
Visualisieren Sie Ihre Daten ganz einfach mit Python Seaborn.
Lesen und Schreiben von CSV mit Python
Verschieben Sie Daten mit Python Change / Delete (Writer und Reader) nach LDAP.
Mehrfachintegration mit Python und Sympy
Lösen mit Ruby, Perl, Java und Python AtCoder ABC 065 C-te Potenz
Bis Python auf Apache läuft
Verarbeiten Sie Pubmed .xml-Daten mit Python
Datenanalyse beginnend mit Python (Datenvisualisierung 1)
Koexistenz von Python2 und 3 mit CircleCI (1.0)
Datenanalyse beginnend mit Python (Datenvisualisierung 2)
Anwendung von Python: Datenbereinigung Teil 2: Datenbereinigung mit DataFrame
Sugoroku-Spiel und Zusatzspiel mit Python
FM-Modulation und Demodulation mit Python
Greifen Sie mit Python auf die Web-API zu, um IoT-Daten zu registrieren / zu erfassen (dweet.io, Requests, HTTPie).