У меня есть библиотека, написанная в Scala, которая имеет некоторые функции для загрузки данных из ряда форматов измерительных данных и выполнения некоторых вычислений. Эти функции работают на версии Scala версии DataFrame
.
Теперь я хочу использовать эти библиотеки в коде Python с PySpark. Я написал некоторые вспомогательные объекты (так как моя библиотека использует множество имплицитов в объектах пакета), чтобы помочь вызывать материал из Python, и мне это удается: (spark
- это Python SparkSession
)
sdf = spark._jvm.com.mycompany.PyApiFooHelper.loadFooMeasuringData(spark._jsparkSession, "hdfs:///some/where")
sCalcResult = spark._jvm.com.mycompany.PyApiBarCalculationHelper.doBarCalculation(sdf)
Когда я хочу sCalcResult
в Python, я в настоящее время делаю это как описано в этом вопросе, регистрируя временное представление и принося его в:
sCalcResult.createOrReplaceTempView("sCalcResult")
calcResult = spark._wrapped.table("sCalcResult")
Однако я нахожу это уродливым, потому что это может привести к столкновениям имен, когда "скрывать это" для моих коллег-ученых, потому что функции должны создавать временные таблицы каждый раз. Или я генерирую случайные имена таблиц, но тогда у меня может быть масса столов, которые уже не нужны, после некоторого времени.
Итак, есть ли функция вроде:
pythonDataFrame = scalaToPythonDataframe(scalaDataFrame)
У Python _jdf
поле _jdf
чтобы получить Java/Scala DF, поэтому kludging вокруг использования временного представления не может быть... Или это?
EDIT: В настоящее время я использую Spark 2.3.
Я посмотрел на исходный код Spark и нашел решение.
DataFrame
имеет конструктор с двумя аргументами, который принимает ссылку на JVM DF и SQLContext
в своем варианте Python.
SQLContext
получается из SparkSession
через его поле _wrapped
или из другого DataFrame
через его поле sql_ctx
.
Итак, это делается так:
from pyspark.sql import DataFrame
# Use Spark DataSource API instead of explicit method
df = spark.read.format("com.mycompany.formats.foo").load("hdfs:///some/where")
sCalcResult = spark._jvm.com.mycompany.PyApiBarCalculationHelper.doBarCalculation(df._jdf)
barCalcResult = DataFrame(sCalcResult, spark._wrapped)