Spark DataFrame 如何区分不同的 VectorUDT 对象?
How does Spark DataFrame distinguish between different VectorUDT objects?
我正在尝试了解 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()
四个矢量值的列在 printSchema()
(或 schema
)中看起来相同:
root
|-- DenseVector: vector (nullable = true)
|-- SparseVector: vector (nullable = true)
|-- old_DenseVector: vector (nullable = true)
|-- old_SparseVector: vector (nullable = true)
但是当我逐行检索它们时,结果发现它们是不同的:
> 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'>
我对 vector
类型的含义感到困惑(在编写 UDF 时等同于 VectorUDT
)。 DataFrame
如何知道它在每个 vector
列中具有四种向量类型中的哪一种?这些向量列中的数据是存储在 JVM 中还是 python VM 中?为什么 VectorUDT
可以存储在 DataFrame
中,如果它不是官方类型之一 listed here?
(我知道来自 mllib.linalg
的四种矢量类型中的两种最终将被弃用。)
how come VectorUDT can be stored in the DataFrame
UDT
a.k.a User Defined Type 应该是这里的提示。 Spark 提供(现在是私有的)机制来在 DataFrame
中存储自定义对象。您可以查看我对 或 Spark 源的回答以获取详细信息,但长话短说,它就是关于解构对象并将它们编码为 Catalyst 类型。
I'm confused about the meaning of vector type
很可能是因为您看错了东西。简短描述很有用,但不能确定类型。相反,您应该检查架构。让我们创建另一个数据框:
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])|
## +-------------+-------------+
并检查数据类型:
{s.name: type(s.dataType) for s in df.schema}
## {'ml_v': pyspark.ml.linalg.VectorUDT,
## 'mllib_v': pyspark.mllib.linalg.VectorUDT}
如您所见,UDT 类型是完全限定的,所以这里没有混淆。
How does the DataFrame know which of the four vector types it has in each vector column?
如上所示DataFrame
只知道它的模式并且可以区分ml
/ mllib
类型但不关心向量变体(稀疏或密集)。
向量类型由其 type
字段(一个 byte
字段,0 -> 稀疏,1 -> 密集)确定,但总体架构相同。 ml
和 mllib
之间的内部表示也没有区别。
Is the data in those vector columns stored in the JVM or in Python
DataFrame
是一个纯 JVM 实体。 Python 互操作性是通过耦合的 UDT 类:
实现的
- Scala UDT 可以定义
pyUDT
属性。
- Python UDT 可以定义
scalaUDT
属性。
我正在尝试了解 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()
四个矢量值的列在 printSchema()
(或 schema
)中看起来相同:
root
|-- DenseVector: vector (nullable = true)
|-- SparseVector: vector (nullable = true)
|-- old_DenseVector: vector (nullable = true)
|-- old_SparseVector: vector (nullable = true)
但是当我逐行检索它们时,结果发现它们是不同的:
> 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'>
我对 vector
类型的含义感到困惑(在编写 UDF 时等同于 VectorUDT
)。 DataFrame
如何知道它在每个 vector
列中具有四种向量类型中的哪一种?这些向量列中的数据是存储在 JVM 中还是 python VM 中?为什么 VectorUDT
可以存储在 DataFrame
中,如果它不是官方类型之一 listed here?
(我知道来自 mllib.linalg
的四种矢量类型中的两种最终将被弃用。)
how come VectorUDT can be stored in the DataFrame
UDT
a.k.a User Defined Type 应该是这里的提示。 Spark 提供(现在是私有的)机制来在 DataFrame
中存储自定义对象。您可以查看我对
I'm confused about the meaning of vector type
很可能是因为您看错了东西。简短描述很有用,但不能确定类型。相反,您应该检查架构。让我们创建另一个数据框:
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])|
## +-------------+-------------+
并检查数据类型:
{s.name: type(s.dataType) for s in df.schema}
## {'ml_v': pyspark.ml.linalg.VectorUDT,
## 'mllib_v': pyspark.mllib.linalg.VectorUDT}
如您所见,UDT 类型是完全限定的,所以这里没有混淆。
How does the DataFrame know which of the four vector types it has in each vector column?
如上所示DataFrame
只知道它的模式并且可以区分ml
/ mllib
类型但不关心向量变体(稀疏或密集)。
向量类型由其 type
字段(一个 byte
字段,0 -> 稀疏,1 -> 密集)确定,但总体架构相同。 ml
和 mllib
之间的内部表示也没有区别。
Is the data in those vector columns stored in the JVM or in Python
DataFrame
是一个纯 JVM 实体。 Python 互操作性是通过耦合的 UDT 类:
- Scala UDT 可以定义
pyUDT
属性。 - Python UDT 可以定义
scalaUDT
属性。