У меня есть кадр данных, который выглядит следующим образом:
# +----+------------+----------+-----------+
# | id | c_type_1 | c_type_2 | c_type_3 |
# +----+------------+----------+-----------+
# | 1 | null | null | r |
# | 2 | a | null | null |
# | 3 | null | null | null |
# +---+-------------+----------+-----------+
Мне нужно преобразовать его во что-то вроде этого:
# +----+------------+------------+
# | id | c_type | c_type_val |
# +----+------------+------------+
# | 1 | c_type_3 | r |
# | 2 | c_type_1 | a |
# | 3 | null | null |
# +---+-------------+------------+
Каждая строка имеет только одно значение c_type или всеЗначения c_type будут нулевыми.
В настоящее время я растапливаю строки следующим образом:
def melt(df, id_cols, value_cols, c_type, c_value):
v_arr = []
for c in value_cols:
v_arr.append(struct(lit(c).alias(c_type), col(c).alias(c_value)))
vars_and_vals = array(*v_arr)
tmp = df.withColumn("vars_and_vals", explode(vars_and_vals))
cols = id_cols + [
col("vars_and_vals")[x].alias(x) for x in [c_type, c_value]]
return tmp.select(*cols)
melted = melt(df, df.columns[:1], df.columns[1:4], 'c_type', 'c_type_val')
melted.filter(melted.c_type_val.isNotNull()).show()
Проблема состоит в том, что фильтрация нулевых значений для c_type_val отфильтровывает строку для id == 3(любые строки с нулевым c_type).Мне нужен способ плавления и фильтрации, чтобы сохранить третью строку с нулевым c_type и значением.