Как получить имена столбцов как часть оператора withColumn согласно некоторому условию в фрейме данных pyspark? - PullRequest
0 голосов
/ 26 марта 2019

У меня есть фрейм данных 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)))))

Я сделал это в python перед использованием iterrows () но я не могу в pyspark.Примечание: - Это большой набор данных.

1 Ответ

0 голосов
/ 26 марта 2019

Для этого можно использовать concat_ws и when.

Сначала создайте список имен столбцов для столбцов «домен». Вы должны настроить это в соответствии со своими потребностями, но в зависимости от того, что вы указали в вопросе, может сработать следующее:

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|
#+----+-------+-------+-------+-----------+-------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...