使用JEP将数据帧从Scala传递到python

时间:2019-05-12 08:40:42

标签: python scala apache-spark jep

这就是我想要做的:

  1. 我将数据读入了scala
  2. 提取几列
  3. 使用JEP将创建的数据框传递给Python脚本
  4. Python脚本将数据框转换为熊猫,然后执行一些操作并将其返回

但是我不确定如何将数据帧传递给python脚本。 这是python脚本(这只是示例脚本,而不是实际的脚本):

import findspark
findspark.init()
import pandas as pd
#from pyspark.sql import types.*
from pyspark.sql import DataFrame as dataframe

def tes(df: dataframe):
    df = df.toPandas()
    df['concatenate'] = df['country'] + df['datasourceProvidedCountry']
    return dataframe(df)

,并且不断出现以下错误:

jep.JepException: <class 'ImportError'>: py4j.protocol
  at /usr/local/lib64/python3.6/site-packages/jep/java_import_hook.__getattr__(java_import_hook.py:57)
  at /home/hadoop/testpy.<module>(testpy.py:5)
  at jep.Jep.run(Native Method)
  at jep.Jep.runScript(Jep.java:359)
  at jep.Jep.runScript(Jep.java:335)
  ... 49 elided
Caused by: java.lang.ClassNotFoundException: py4j.protocol
  at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
  ... 52 more
spark-shell --conf spark.driver.extraLibraryPath=:/usr/local/lib64/python3.6/site-packages/jep:/usr/local/lib/python3.6/site-packages/py4j/ --jars /home/hadoop/jep-3.8.2.jar

有人可以建议我如何使用Jep将数据帧从scala传递到pyspark(如果重复,请指向正确的线程,因为我找不到一个)?

2 个答案:

答案 0 :(得分:0)

我有相同的要求,并尝试使用Jep。不幸的是,Jep不适用于此用例。

找不到的py4j.protocol是由Jep ClassEnquirer引起的,当python和jave的库名称相同时,Jep会考虑使用Java库。您可以通过从Java应用程序的spark包中排除py4j来解决此问题,或者创建自定义的ClassEnquirer来考虑python py4j。

您还需要更新Jep构造函数,将useSubInterpreter值设置为false并重建它。

public Jep(JepConfig config) throws JepException {
    this(config, false);
}

现在应解决该错误。但是,传递给python函数的对象是包含Java引用的PyObject,它不是pyspark数据框对象,因此它没有toPandas()函数。

另一种方法是使用gRPC或Apache thrift,您可以检查文档以了解更多详细信息。

答案 1 :(得分:0)

使用Apache Spark可以将数据从Apache Arrow适当(JVM)传递到Python代码-因为2.3 Spark使用的箭头格式可以在JVM和CPython中使用。

有关灵感,请参见https://fossies.org/diffs/spark/2.3.3_vs_2.4.0/sql/core/src/test/scala/org/apache/spark/sql/execution/arrow/ArrowConvertersSuite.scala-diff.html

我使用jep(Java嵌入式Python)DirectNDArray(“堆外”,“零副本”)在同一进程(无套接字)中在JVM和CPython代码之间传递数据。

请让我知道这看起来是否足够好,并将改善此答案。