[英]Dynamically Expand Arraytype() Columns in Structured Streaming PySpark
我有以下 DataFrame:
root
|-- sents: array (nullable = false)
| |-- element: integer (containsNull = true)
|-- metadata: array (nullable = true)
| |-- element: float (containsNull = true)
+----------+---------------------+
|sents |metadata |
+----------+---------------------+
|[1, -1, 0]|[0.4991, 0.5378, 0.0]|
|[-1] |[0.6281] |
|[-1] |[0.463] |
+----------+---------------------+
我想将每个数组项动态扩展为自己的列,使其看起来如下所示:
+--------+--------+--------+-----------+-----------+-----------+
|sents[0]|sents[1]|sents[2]|metadata[0]|metadata[1]|metadata[2]|
+--------+--------+--------+-----------+-----------+-----------+
| 1| -1| 0| 0.4991| 0.5378| 0.0|
| -1| null| null| 0.6281| null| null|
| -1| null| null| 0.463| null| null|
+--------+--------+--------+-----------+-----------+-----------+
但是在结构化流中,动态处理有很多限制:
我尝试了以下方法:
numcol = df.withColumn('phrasesNum', F.size('sents')).agg(F.max('phrasesNum')).head()
df = df.select(*[F.col('sents')[i] for i in range(numcol[0])],*[F.col('metadata')[i] for i in range(numcol[0])])
还:
df_sizes = df.select(F.size('sents').alias('sents'))
df_max = df_sizes.agg(F.max('sents'))
nb_columns = df_max.collect()[0][0]
d = c.select(*[F.map_values(c['metadata'][i]).getItem(0).alias('confidenceIntervals'+"{}".format(j)).cast(DoubleType()) for i,j in enumerate(range(F.size('sents')))],
*[c['sents'][i].alias('phraseSents'+"{}".format(j)).cast(IntegerType()) for i,j in enumerate(range(nb_columns))])
但我不能在结构化流中使用 .head()、.collect() 或 .take() 之类的东西来创建指示要动态创建的列数的数值变量。 有任何想法吗??
谢谢大家
如果您知道columns you need
或max size of each array column.
那么您可以在without collecting to driver
节点( first、take、collect 等)的情况下做到这一点。 在这里,我假设两列的max size of 3
,列需要0,1,2.
同样在流式传输中,数据帧之间不能有不同的模式(列)。
cols=['0','1','2']
from pyspark.sql import functions as F
df.withColumn("struct1", F.struct(*[F.struct((F.col("sents")[int(x)]).alias('sents[{}]'.format(x))) for x in cols]))\
.withColumn("struct2", F.struct(*[F.struct((F.col("metadata")[int(x)]).alias('metadata[{}]'.format(x))) for x in cols]))\
.select(*["struct1.{}.*".format(x) for x in ['col{}'.format((int(x)+1)) for x in cols]],
*["struct2.{}.*".format(x) for x in ['col{}'.format((int(x)+1)) for x in cols]]).show()
#+--------+--------+--------+-----------+-----------+-----------+
#|sents[0]|sents[1]|sents[2]|metadata[0]|metadata[1]|metadata[2]|
#+--------+--------+--------+-----------+-----------+-----------+
#| 1| -1| 0| 0.4991| 0.5378| 0.0|
#| -1| null| null| 0.6281| null| null|
#| -1| null| null| 0.463| null| null|
#+--------+--------+--------+-----------+-----------+-----------+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.