首页 > 解决方案 > 如何根据pyspark数据框中的某些条件获取列名作为withColumn语句的一部分?

问题描述

我有一个带有虚拟编码值的 pyspark 数据框,如下所示:

    user    domain1      domain2     domain3..........  conversions

    abcd    1            0           0                   1
    gcxe    0            1           2                   0
    .       .            .           .                   .
    .       .            .           .                   .
    .       .            .           .                   .
    .       .            .           .                   .

我想要做的是创建一个列'vw_format',每行'vw_format'都包含一个字符串,该字符串包含该行中不为0的列名。所以我想要一个这样的专栏:

    'vw_format'

    '1|d domain1'
    '0|d domain1 domain3'
         .
         .
         .

我该怎么做呢?我不能使用 collect() 因为我有一个大数据集。

“1|” 和“0|” 只代表我已经实现的转换列。

我试图这样做,但没有奏效:

df = df.withColumn("conversions",F.when(col('conversions') == 1, '1 10 | ').otherwise("-1 | "))

line = []
def myfunc(x):

    line = ""+x+""
    return line

df = df.withColumn('vw_format', sf.concat(sf.col('conversions'),sf.lit('d '), sf.lit(when(sf.col([i for i in list])!=1,myfunc(i)))))

在使用 iterrows() 之前我已经在 python 中完成了这个,但我不能在 pyspark 中。注意:- 这是一个大型数据集。

标签: pythonpyspark

解决方案


您可以使用concat_wsandwhen来完成此操作。

首先为“域”列创建列名列表。您必须对此进行调整以满足您的需求,但根据您在问题中提供的内容,以下可能会起作用:

domains = [c for c in df.columns if c.lower().startswith("domain")]
print(domains)
#['domain1', 'domain2', 'domain3']

现在用 a作为分隔符连接conversions列和文字字符串。接下来将此结果与其中具有非零值的每一列连接起来,并以空格作为分隔符。"d""|"domains

我们利用如果不满足条件并且指定 no 时默认when返回的事实。(连接将跳过s。)nullotherwisenull

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|
#+----+-------+-------+-------+-----------+-------------------+

推荐阅读