2016-09-08 3 views
1

def column_concat(a,b): return concat(a,b)
searches_df = searches_df.withColumn('unique_id',reduce(column_concat,(searches_df[col] for col in search_parameters)))
Wie verketten Sie mehrere Spalten in einem Datenrahmen in eine andere Spalte, wenn einige Werte null sind?

Dies funktioniert, außer wenn eine Spalte einen Nullwert enthält, dann ist die gesamte verkettete Zeichenfolge null. Ich möchte den Platzhalter oder ein Zeichen stattdessen in der verketteten Zeichenfolge.

Antwort

4

mit dem folgenden Datenrahmen:

df = sqlContext.createDataFrame([("foo", "bar"), ("baz", None)], 
           ('a', 'b')) 
df.show() 

+---+----+ 
| a| b| 
+---+----+ 
|foo| bar| 
|baz|null| 
+---+----+ 

Eine Lösung ist ein UDF zu verwenden, um Filter/ersetzen, die null (s), zB:

import pyspark.sql.functions as F 
from pyspark.sql.types import StringType 

concat_udf = F.udf(lambda cols: "".join([x if x is not None else "*" for x in cols]), StringType()) 
df.withColumn("unique_id", concat_udf(F.array("a", "b"))).show() 

das ergibt:

+---+----+---------+ 
| a| b|unique_id| 
+---+----+---------+ 
|foo| bar| foobar| 
|baz|null|  baz*| 
+---+----+---------+ 

Alternativ:

import pyspark.sql.functions as F 

def myConcat(*cols): 
    return F.concat(*[F.coalesce(c, F.lit("*")) for c in cols]) 

df.withColumn("unique_id", myConcat("a", "b")).show() 

die ebenfalls ergibt:

+---+----+---------+ 
| a| b|unique_id| 
+---+----+---------+ 
|foo| bar| foobar| 
|baz|null|  baz*| 
+---+----+---------+ 
+0

Thank you! Ich überwinde das Problem, indem ich stattdessen concat_ws verwende, aber diese Lösungen sind nützlich und notwendig, wenn ein Platzhalter benötigt wird. –

Verwandte Themen