我在理解spark udf返回类型时遇到了麻烦。我有两个pyspark数据框。
DF1包含每行ID的列表,例如
+-------------+
|seq |
+-------------+
|[1, 2, 3, 4]|
|[5, 6, 7] |
DF2已将编码后的功能组合到SparseVector中,并分配给每个唯一的ID,例如
+--------+--------------------+
|ID| features|
+--------+--------------------+
| 1|(67,[2,36,42,46,5...|
| 2|(67,[4,36,42,46,5...|
现在,我的目标是将数据以形状(N个样本,sequence_length,n_features)的形式提供给LSTM。目前,我正在将稀疏向量转换为密集向量,然后使用udf,但这变得无法使用更多功能进行存储。然后我尝试使用稀疏格式来节省内存:
import pyspark.sql.functions as fun
from pyspark.mllib.linalg import VectorUDT
features = spark.sparkContext.broadcast(
df2.rdd.collectAsMap())
def add_features(s):
res = []
for each in s:
res += [features.value.get(each)]
return res
features_udf = fun.udf(add_features, returnType=ArrayType(VectorUDT()))
df1.withColumn('seq_features', features_udf('seq')) \
.write.mode('overwrite').parquet(path+ 'data_df')
但是我得到了错误:
Py4JJavaError: An error occurred while calling o93.parquet.
: org.apache.spark.SparkException: Job aborted.
at org.apache.spark.sql.execution.datasources.FileFormatWriter$.write(FileFormatWriter.scala:224)
TLDR :我需要3维格式的数据。行表示序列数,列表示每个序列中元素的数量(可变长度),第三个dim表示稀疏或密集格式的编码特征。我所拥有的是一个数据帧,用于指定每一行中ID的顺序,以及一个将ID映射至要素的数据帧。由于数据非常大,因此我需要以最佳方式将这两个数据帧合并。
我正在寻找的结果:
+---------------------------------------------+
|seq |
+---------------------------------------------+
|[[features1],[features2],[features3], [features4]]|
|[[features5], [features6], [features7]] |
感谢您的任何建议和帮助。
编辑:Py4JJavaError是因为我应该改用pyspark.ml.linalg中的VectorUDT ...