max*_*max 6 dataframe apache-spark pyspark apache-spark-ml apache-spark-mllib
我正在尝试了解DataFrame列类型.当然,DataFrame不是物化对象,它只是Spark的一组指令,将来转换为代码.但我想象这个类型列表表示在执行操作时可能在JVM内部实现的对象类型.
import pyspark
import pyspark.sql.types as T
import pyspark.sql.functions as F
data = [0, 3, 0, 4]
d = {}
d['DenseVector'] = pyspark.ml.linalg.DenseVector(data)
d['old_DenseVector'] = pyspark.mllib.linalg.DenseVector(data)
d['SparseVector'] = pyspark.ml.linalg.SparseVector(4, dict(enumerate(data)))
d['old_SparseVector'] = pyspark.mllib.linalg.SparseVector(4, dict(enumerate(data)))
df = spark.createDataFrame([d])
df.printSchema()
Run Code Online (Sandbox Code Playgroud)
四个向量值的列在printSchema()(或schema)中看起来相同:
root
|-- DenseVector: vector (nullable = true)
|-- SparseVector: vector (nullable = true)
|-- old_DenseVector: vector (nullable = true)
|-- old_SparseVector: vector (nullable = true)
Run Code Online (Sandbox Code Playgroud)
但是当我逐行检索它们时,它们会变得不同:
> for x in df.first().asDict().items():
print(x[0], type(x[1]))
(2) Spark Jobs
old_SparseVector <class 'pyspark.mllib.linalg.SparseVector'>
SparseVector <class 'pyspark.ml.linalg.SparseVector'>
old_DenseVector <class 'pyspark.mllib.linalg.DenseVector'>
DenseVector <class 'pyspark.ml.linalg.DenseVector'>
Run Code Online (Sandbox Code Playgroud)
我对vector类型的含义感到困惑(相当于VectorUDT编写UDF的目的).如何DataFrame知道每vector列中哪四种矢量类型?这些向量列中的数据是存储在JVM中还是存储在python VM中?如果它不是这里列出的官方类型之一,那怎么来VectorUDT存储呢?DataFrame
(我知道四种矢量类型中的两种,mllib.linalg最终会被弃用.)
为什么VectorUDT可以存储在DataFrame中
UDT又名用户定义类型应该是一个提示.Spark提供(现在是私有的)机制来存储自定义对象DataFrame.您可以在Spark SQL中查看如何为自定义类型定义架构的答案?或者火花源的详细信息,但长话短说,它是关于解构对象并将它们编码为Catalyst类型.
我对矢量类型的含义感到困惑
很可能是因为你看错了.简短描述很有用,但它不能确定类型.相反,您应该检查架构.让我们创建另一个数据框:
import pyspark.mllib.linalg as mllib
import pyspark.ml.linalg as ml
df = sc.parallelize([
(mllib.DenseVector([1, ]), ml.DenseVector([1, ])),
(mllib.SparseVector(1, [0, ], [1, ]), ml.SparseVector(1, [0, ], [1, ]))
]).toDF(["mllib_v", "ml_v"])
df.show()
## +-------------+-------------+
## | mllib_v| ml_v|
## +-------------+-------------+
## | [1.0]| [1.0]|
## |(1,[0],[1.0])|(1,[0],[1.0])|
## +-------------+-------------+
Run Code Online (Sandbox Code Playgroud)
并检查数据类型:
{s.name: type(s.dataType) for s in df.schema}
## {'ml_v': pyspark.ml.linalg.VectorUDT,
## 'mllib_v': pyspark.mllib.linalg.VectorUDT}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,UDT类型是完全合格的,因此这里没有混淆.
DataFrame如何知道它在每个向量列中的四种向量类型中的哪一种?
如上所示,DataFrame只知道它的模式,可以区分ml/ mllib类型,但不关心矢量变量(稀疏或密集).
矢量类型由其type字段(byte字段,0 - >稀疏,1 - >密集)确定,但整体模式是相同的.在ml和之间的内部表示也没有区别mllib.
这些向量列中的数据是存储在JVM还是Python中
DataFrame是一个纯JVM实体.通过耦合的UDT类实现Python互操作性:
pyUDT属性.scalaUDT属性.