我有一个rdd,它的每一行都包含三种数据类型。例如
from pyspark.sql import SparkSession
from scipy.sparse import csc_matrix
import numpy as np
from pyspark.sql.types import StructType,StructField,FloatType,IntegerType,ArrayType
# create sparse matrix
row = np.array([0, 2, 2, 0, 1, 2])
col = np.array([0, 0, 1, 2, 2, 2])
data = np.array([1, 2, 3, 4, 5, 6])
sp_mat = csc_matrix((data, (row, col)), shape=(3, 3))
# create rdd
sqlContext = SparkSession.builder.appName("test").enableHiveSupport().getOrCreate()
sp_data = [(0,12.1,sp_mat),(1,21.32,sp_mat),(2,21.2,sp_mat)]
spare_rdd = sqlContext.sparkContext.parallelize(sp_data)
print(spare_rdd.take(3))
# print
[(0, 12.1, <3x3 sparse matrix of type '<type 'numpy.int64'>' with 6 stored elements in Compressed Sparse Column format>)
,(1, 21.32, <3x3 sparse matrix of type '<type 'numpy.int64'>' with 6 stored elements in Compressed Sparse Column format>)
,(2, 21.2, <3x3 sparse matrix of type '<type 'numpy.int64'>' with 6 stored elements in Compressed Sparse Column format>)]
前两种数据类型是int和float。三种数据类型是稀疏稀疏矩阵。我想将此rdd数据写入配置单元表。但是我不知道保存稀疏矩阵的形式或字段。
所以我的问题如下:
如何为scipy稀疏矩阵创建蜂巢表?
CREATE EXTERNAL TABLE spare_table(
id int,
value float,
... <---- One or more field or struct for scipy sparse matrix
)
stored as orc tblproperties ("orc.compress"="SNAPPY");
如何通过pyspark将scipy稀疏矩阵保存到上表中?如果我通过df = sqlContext.createDataFrame(spare_rdd, schema=['id', 'value', 'scipy'])
将rdd转换为数据帧,则会显示错误:
TypeError:不支持的类型:
不存储scipy类型的解决方案也是可以接受的。唯一的要求是该解决方案可以支持再次进行稀疏矩阵写入和读取。任何帮助将不胜感激。
答案 0 :(得分:0)
我终于找到了解决方案。我可以将稀疏稀疏矩阵的indices
,indptr
,data
和shape
存储到配置单元表中以实现此目的。当我再次从蜂巢表中读取数据时,我可以基于它们重新创建一个稀疏矩阵。
首先,我应该创建一个配置单元表,如下所示:
CREATE EXTERNAL TABLE spare_table(
id int,
value float,
indices array<int>,
indptr array<int>,
data array<int>,
shape array<int>
)
stored as orc tblproperties ("orc.compress"="SNAPPY");
然后,我通过将稀疏稀疏矩阵分解为indices
,indptr
,data
和shape
将rdd转换为数据帧。
grid_img_df = spare_rdd.map(lambda x: [
x[0]
,x[1]
,x[2].indices.tolist()
,x[2].indptr.tolist()
,x[2].data.tolist()
,[int(shape) for shape in x[2].shape]])
df = sqlContext.createDataFrame(grid_img_df, schema=['id','value','indices','indptr','data','shape'])
df.show()
+---+-----+------------------+------------+------------------+------+
| id|value| indices| indptr| data| shape|
+---+-----+------------------+------------+------------------+------+
| 0| 12.1|[0, 2, 2, 0, 1, 2]|[0, 2, 3, 6]|[1, 2, 3, 4, 5, 6]|[3, 3]|
| 1|21.32|[0, 2, 2, 0, 1, 2]|[0, 2, 3, 6]|[1, 2, 3, 4, 5, 6]|[3, 3]|
| 2| 21.2|[0, 2, 2, 0, 1, 2]|[0, 2, 3, 6]|[1, 2, 3, 4, 5, 6]|[3, 3]|
+---+-----+------------------+------------+------------------+------+
最后,我把它写在蜂巢中。
df.registerTempTable("df_table")
sqlContext.sql(""" INSERT overwrite TABLE spare_table
select id
,value
,indices
,indptr
,data
,shape
from df_table""")
从配置单元表读取数据并将其转换为稀疏稀疏矩阵的代码如下:
rdd = df.rdd.map(lambda row:(row.id,row.value,csc_matrix((row.data,row.indices,row.indptr),shape=row.shape)))