Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Как выполнять udfs для нескольких столбцов динамически

Автор вопроса: CommunityОтветов: 4

У меня есть 30 столбцов, таких как DPF_1,DPF_2,DPF_3......DPF_30, к которым мне нужно применить кадры данных. Все 30 столбцов имеют тип данных String. Мое требование состоит в том, чтобы преобразовать все значения "Na", присутствующие в этих 30 столбцах, в "null".

Я пробовал код ниже, но он не динамический.

def udf_A(x:StringType()):
    if x == "Na": return "null"
    else:return x
udf_B = udf(udf_A, StringType())

df.withColumn("DPF_1" udf_B("DPF_1"))
df.withColumn("DPF_2" udf_B("DPF_2"))
.
.
repeated till DPF_30

Теперь я хочу, чтобы этот процесс выполнялся динамически в pyspark/scala, потому что более поздние столбцы могут увеличиваться с разными именами столбцов.

  • Вы всегда можете использовать regexp_replace для преобразования Na в null philantrovert 16.01.2018
  • @philantrovert, у меня много других требований. что можно легко сделать с помощью UDFS 16.01.2018
  • Итак, вы пытаетесь преобразовать Na в Null и сделать кучу других вещей с помощью одного UDF? philantrovert 16.01.2018
  • @ филантроверт: да 16.01.2018

apache-sparkpysparkapache-spark-sqlscalapyspark-sql

Ответы

Ответ 1 · LUZO

Попробуйте этот код ниже, надеюсь, это поможет.

def udf_A(x:StringType()):
    if x == "Na": return "null"
    else:return x
udf_B = udf(udf_A, StringType())

import pyspark.sql.functions as psf

for c in df.dtypes:
    if "string" in c[1]:
        df=df.withColumn(c[0],udf_B(psf.col(c[0])))
df.show()

Здесь df.dtypes дает вам массив кортежей с именем столбца и типом данных.

[('DPF_1', 'string'), ('DPF_2', 'string'), ('DPF_3', 'string')... ]

c[0] обозначает имя столбца, а c[1] обозначает тип данных, который в вашем случае равен string.

Ответ 2 · рейтинг 2 · Raphael Roth

Вот решение на Scala:

// columns which you want to keep
val colsToSelect : Seq[Column] = ???
// columns which are applied to UDF
val selectUDFs : Seq[Column] = (1 to 30).map(i => udf_B(col(s"DPF_$i")).as(s"DPF_$i"))

df.select((colsToSelect++selectUDFs):_*)

Ответ 3 · рейтинг 2 · Ramesh Maharjan

Вы можете просто преобразовать кадр данных 30 столбцов в na dataframe и применить метод replace как

df.na.replace(df.columns, Map("Na" -> "null"))

Вы замените все строки Na на строку null.

Ответ 4 · рейтинг 1 · Leo C

Один из подходов в Scala состоит в том, чтобы собрать список столбцов с использованием фильтра и пройти по списку, чтобы преобразовать DataFrame с помощью вашей UDF:

val cols = df.columns.filter(_.startsWith("DPF_"))

val df2 = cols.foldLeft( df )( (acc, c) => acc.withColumn(c, udf_B(df(c))) )

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы