Apache spark 如何在mapPartitions返回的迭代器中的每个RDD上映射RDD函数

Apache spark 如何在mapPartitions返回的迭代器中的每个RDD上映射RDD函数,apache-spark,pyspark,rdd,apache-spark-mllib,Apache Spark,Pyspark,Rdd,Apache Spark Mllib,我有一个数据框,其中包含文档iddoc\u id,每个文档中一组行的行idline\u id,以及每行向量的密集向量表示。对于每个文档(doc\u id),我希望将表示每行的向量集转换为mllib.linalg.distributed.BlockMatrix 将整个数据帧的向量或通过doc_id过滤的数据帧的向量转换为块矩阵,首先将向量转换为(numRows,numCols),DenseMatrix)。下面是一个编码的例子 但是,我无法将mapPartition返回的Iterator[(numR

我有一个数据框,其中包含文档id
doc\u id
,每个文档中一组行的行id
line\u id
,以及每行向量的密集向量表示。对于每个文档(
doc\u id
),我希望将表示每行的向量集转换为
mllib.linalg.distributed.BlockMatrix

将整个数据帧的向量或通过
doc_id
过滤的数据帧的向量转换为
块矩阵
,首先将向量转换为
(numRows,numCols),DenseMatrix)
。下面是一个编码的例子

但是,我无法将
mapPartition
返回的
Iterator[(numRows,numCols),DenseMatrix)]
的RDD转换为每个
doc\u id
分区的单独
块矩阵

我的集群有3个工作节点,每个节点有16个内核和62 GB内存


导入并启动spark

从pyspark.sql导入SparkSession
从pyspark.sql导入函数为F
从pyspark.sql导入类型为T
从pyspark.mllib.random导入RandomRDDs
从pyspark.mllib.linalg导入向量
从pyspark.mllib.linalg导入VectorUDT
从pyspark.mllib.linalg导入矩阵
从pyspark.mllib.linalg导入MatrixUDT
来自pyspark.mllib.linalg.distributed import BlockMatrix
火花=(
SparkSession.builder
.master(“纱线”)
.appName(“linalg_测试”)
.getOrCreate()
) 
创建测试数据帧

nRows=25000
“”“创建ids数据帧”“”
温=(W
.partitionBy(F.col('doc_id'))
.rowsBetween(W.unboundedreceiding,W.currentRow)
)
df_ID=(
火花点火范围(0,nRows,1)
.withColumn('rand1',(F.rand(seed=12345)*50).cast(T.IntegerType())
.withColumn('doc_id',F.floor(F.col('rand1')/3).cast(T.IntegerType())
.带列('int',F.lit(1))
.withColumn('line_id',F.sum(F.col('int'))。over(win))
.选择('id'、'doc\u id'、'line\u id')
)
“”“创建矢量数据帧”“”
df_vecSchema=T.StructType([
T.StructField('vectors',T.StructType([T.StructField('vectors',VectorUDT())])),
T.StructField('id',T.LongType())
])
vecDim=50
df_vec=(
spark.createDataFrame(
RandomRDDs.normalvectordd(sc,numRows=nRows,numCols=vecDim,seed=54321)
.map(λx:Row(vectors=vectors.densite(x)))
.zipWithIndex(),schema=df_vecSchema)
.选择('id','vectors.*')
)
“”“创建最终测试数据帧”“”
df_SO=(
df_-id.join(df_-vec,on='id',how='left')
.选择('doc\u id'、'line\u id'、'vectors')
.orderBy('doc\u id','line\u id')
)
numDocs=df_SO.agg(F.countDistinct(F.col('doc_id'))).collect()[0][0]
#numDocs=df_SO.groupBy('doc_id').agg(F.count(F.col('line_id'))).count()
df_SO=df_SO.repartition(numDocs,'doc_id')
RDD函数用于从向量列创建矩阵

def vec2mat(世界其他地区):
报税表(
(第1行,第0行),
密集矩阵(1,vecDim,(row.vectors.toArray().tolist()),)
从每个
行id
向量创建密集矩阵

mat=df_SO.rdd.map(vec2mat)
从DenseMatrix的RDD创建分布式块矩阵

blk_mat=块矩阵(mat,1,vecDim)
检查输出

blk_mat

blk_材料块。取(1)
[((273,0),
DenseMatrix(1,50、[1.749、-1.4873、-0.3473、0.716、2.3916、-1.5997、-1.7035、0.0105、-0.0579、0.3074、-1.8178、-0.2628、0.1979、0.6046、0.4566、0.4063、[0]))

问题 在使用
mapPartitions
转换
doc\u id
的每个分区之后,我无法使用相同的东西。
mapPartitions
函数可以工作,但我无法将它返回的RDD转换为
块矩阵

RDD函数为每个
文档id
分区分别从每个
行id
向量创建密集矩阵

def vec2mat(国际热核实验堆): 收益率[((第1行,第1行,第0行), 密集矩阵(1,vecDim,(row.vectors.toArray().tolist()),) 国际热核实验堆中的世界其他地区]
为每个
文档id
分区分别从每个
行id
向量创建密集矩阵

mat_doc=df_SO.rdd.mapPartitions(vec2mat\u p,preserveSpatiting=True)
检查

mat_doc
PythonRDD[4991]在PythonRDD.scala的RDD处:48
mat_测试。取(1)
[[((0,0),
DenseMatrix(1,50、[1.814、-1.1681、-2.1887、-0.5371、-0.7509、2.3679、0.2795、1.4135、-0.3584、0.5059、-0.6429、-0.6391、0.0173、1.2109、1.804、-0.9402],0)),
((1, 0),
DenseMatrix(1,50、[0.3884、-1.451、-0.0431、-0.4653、-2.4541、0.2396、1.8704、0.8471、-2.5164、0.1298、-1.2702、-0.1286、0.9196、-0.7354、-0.1816、-0.4553、-0)),
((2, 0),
DenseMatrix(1,50,[0.1382,1.6753,0.9563,-1.5251,0.1753,0.9822,0.5952,-1.3924,…,0.9636,-1.7299,0.2138,-2.5694,0.1701,0.2554,-1.4879,-1.6504,0)),
...]]
检查类型

(材料文件
.过滤器(λp:len(p)>0)
.map(lambda mlst:[(类型(m[0]),(类型(m[0][0]),类型(m[0][1])),类型(m[1]),用于mlst中的m])
.first()
)
[(tuple,(int,int),pyspark.mllib.linalg.DenseMatrix),
(tuple,(int,int),pyspark.mllib.linalg.DenseMatrix),
(tuple,(int,int),pyspark.mllib.linalg.DenseMatrix),
...]
但是,运行以下命令似乎是正确的:

(材料文件
.过滤器(λp:len(p)>0)
.map(lambda mlst:[块矩阵((m[0],m[1])[0],1,vecDim)用于mlst中的m])
.first()
)
导致以下类型错误:

TypeError:块应该是子矩阵块的RDD,作为((int,int),矩阵)元组,got
不幸的是,错误很快就停止了,并且没有告诉我它得到了什么

而且,我不能