Как объединить два столбца фрейма данных spark с нулевыми значениями, но получить одно значение

#apache-spark #pyspark #apache-spark-sql #concatenation

Вопрос:

У меня есть две колонки в моем фрейме данных spark:

Имя И фамилия
 Херри нуль
нуль Конг 
 Утка Утка77
 Тинь-Тинь_ли
 Хуонг нуль
нуль Нгон
 Ли нуль

Мое требование состоит в том, чтобы добавить новый столбец в фрейм данных, объединив вышеуказанные 2 столбца
, но значение нового столбца будет одним из двух, значение старого столбца не равно нулю
Как это сделать в пыспарке ?
Ожидаемый результат:
Имя-Имя-Имя-Имя-Имя
 Херри нуль, Херри
нуль, Удача, Удача.
 Утка Утка77 Утка
 Тинь Тинь_ли Тинь
 Хуонг нуль Хуонг
нуль Нгон Нгон
 Ли нуль Ли

Ответ №1:

вы можете coalesce работать с » pyspark.sql.функции`,

 from pyspark.sql import functions as f

df.withColumn("name",f.coalesce("name_ls","name_mg")).show()

 ------- ------- ----- 
|name_ls|name_mg| name|
 ------- ------- ----- 
|  Herry|   null|Herry|
|   null|   Cong| Cong|
|   Duck| Duck77| Duck|
|   Tinh|Tin_Lee| Tinh|
|  Huong|   null|Huong|
|   null|   Ngon| Ngon|
|    Lee|   null|  Lee|
 ------- ------- ----- 
 

Комментарии:

1. это сработало для моего кода, спасибо, Суреш !

Ответ №2:

Вы можете сделать это с помощью оператора «когда-в противном случае»

Когда — В противном случае — Сначала проверяет ,равно ли name_mg значение Null , заменяет на name_ls , elif Не равно нулю , проверяет, name_ls не равно ли значение Null, заменяет на name_ls

Подготовка Данных

 input_str = """
  Herry   null
  null    Cong   
  Duck    Duck77
  Tinh    Tin_Lee
  Huong   null
  null    Ngon
  Lee     null
""".split()

input_values = list(map(lambda x: x.strip() if x.strip() != 'null' else None, input_str))

cols = list(map(lambda x: x.strip() if x.strip() != 'null' else None, "name_ls,name_mg".split(',')))
        
n = len(input_values)
n_cols = 2

input_list = [tuple(input_values[i:i n_cols]) for i in range(0,n,n_cols)]

sparkDF = sql.createDataFrame(input_list, cols)

sparkDF.show()

 ------- ------- 
|name_ls|name_mg|
 ------- ------- 
|  Herry|   null|
|   null|   Cong|
|   Duck| Duck77|
|   Tinh|Tin_Lee|
|  Huong|   null|
|   null|   Ngon|
|    Lee|   null|
 ------- ------- 
 

Когда — В противном случае

 sparkDF = sparkDF.withColumn('name',F.when(F.col('name_mg').isNull()
                      ,F.col('name_ls')).when(F.col('name_ls').isNotNull(),F.col('name_ls'))
                                        .otherwise(F.col('name_mg'))
              )

sparkDF.show()

 ------- ------- ----- 
|name_ls|name_mg| name|
 ------- ------- ----- 
|  Herry|   null|Herry|
|   null|   Cong| Cong|
|   Duck| Duck77| Duck|
|   Tinh|Tin_Lee| Tinh|
|  Huong|   null|Huong|
|   null|   Ngon| Ngon|
|    Lee|   null|  Lee|
 ------- ------- ----- 
 

Ответ №3:

Если вам нравятся операторы spark SQL так же, как и мне, вы можете рассмотреть функцию NVL.

 from pyspark.sql import SparkSession

spark = SparkSession.builder.getOrCreate()

data = [
    ('Herry', None),
    (None, 'Cong'),
    ('Duck', 'Duck77'),
    ('Tinh', 'Tin_Lee'),
    ('Huong', None),
    (None, 'Ngon'),
    ('Lee', None)
]
schema = ['Name_ls', 'Name_mg']
df = spark.createDataFrame(data, schema)
df.createOrReplaceTempView('tmp')
res_sql = """
    select Name_ls,Name_mg,nvl(Name_ls, Name_mg) Name
    from tmp
"""
res_df = spark.sql(res_sql)
res_df.show(truncate=False)