我有一个带有伪编码值的pyspark数据帧,如下所示:
Checked out revision 0.
我想做的是创建一个“ vw_format”列,其中“ vw_format”的每一行都包含一个字符串,该字符串包含该行中不为0的列名。 所以我想要这样的一列:
user domain1 domain2 domain3.......... conversions
abcd 1 0 0 1
gcxe 0 1 2 0
. . . . .
. . . . .
. . . . .
. . . . .
我该怎么做?我无法使用collect(),因为我的数据集很大。
“ 1 |”和“ 0 |”只是代表我已经实现的转换列。
我尝试过这种方式,但是没有用:
'vw_format'
'1|d domain1'
'0|d domain1 domain3'
.
.
.
在使用iterrows()之前,我已经在python中完成了此操作,但是在pyspark中却不能。 注意:-这是一个大数据集。
答案 0 :(得分:0)
首先为“域”列创建一个列名列表。您必须对此进行调整以满足您的需求,但是根据您在问题中提供的内容,以下方法可能会起作用:
domains = [c for c in df.columns if c.lower().startswith("domain")]
print(domains)
#['domain1', 'domain2', 'domain3']
现在使用conversions
作为分隔符将"d"
列和文字字符串"|"
连接起来。接下来,将此结果与domains
中具有非零值且以空格作为分隔符的每一列连接。
我们利用以下事实:如果不满足条件且未指定when
,则null
默认返回otherwise
。 (串联将跳过null
。)
from pyspark.sql.functions import col, concat_ws, lit, when
df.withColumn(
"vw_format",
concat_ws(
" ",
concat_ws("|", "conversions", lit("d")),
*[when(col(c) != 0, lit(c)) for c in domains]
)
).show(truncate=False)
#+----+-------+-------+-------+-----------+-------------------+
#|user|domain1|domain2|domain3|conversions|vw_format |
#+----+-------+-------+-------+-----------+-------------------+
#|abcd|1 |0 |0 |1 |1|d domain1 |
#|gcxe|0 |1 |2 |0 |0|d domain2 domain3|
#+----+-------+-------+-------+-----------+-------------------+