如何在PySpark中使用分隔符连接多个列?

10

我有一个pyspark Dataframe,希望将其中的3列进行连接。

id |  column_1   | column_2    | column_3
--------------------------------------------
1  |     12      |   34        |    67
--------------------------------------------
2  |     45      |   78        |    90
--------------------------------------------
3  |     23      |   93        |    56
--------------------------------------------

我想合并三列:column_1,column_2,column_3 的值只添加一个连字符"-"
预期结果:
id |  column_1   | column_2    | column_3    |   column_join
-------------------------------------------------------------
1  |     12      |     34      |     67      |   12-34-67
-------------------------------------------------------------
2  |     45      |     78      |     90      |   45-78-90
-------------------------------------------------------------
3  |     23      |     93      |     56      |   23-93-56
-------------------------------------------------------------

如何在Pyspark中实现?谢谢。

2个回答

12
很简单:
from pyspark.sql.functions import col, concat, lit

df = df.withColumn("column_join", concat(col("column_1"), lit("-"), col("column_2"), lit("-"), col("column_3")))

使用concat将所有列用-分隔符连接在一起,您需要使用lit。如果不起作用,您可以使用cast将列类型更改为字符串,col("column_1").cast("string") 更新: 或者您可以使用更动态的方法,使用内置函数concat_ws

pyspark.sql.functions.concat_ws(sep, *cols)

Concatenates multiple input string columns together into a single string column, using the given separator.

>>> df = spark.createDataFrame([('abcd','123')], ['s', 'd'])
>>> df.select(concat_ws('-', df.s, df.d).alias('s')).collect()
[Row(s=u'abcd-123')]

代码:

from pyspark.sql.functions import col, concat_ws

concat_columns = ["column_1", "column_2", "column_3"]
df = df.withColumn("column_join", concat_ws("-", *[F.col(x) for x in concat_columns]))

请帮忙提供建议,如果您对以下问题有任何想法: https://stackoverflow.com/questions/59197109/looking-if-string-contain-a-sub-string-in-differents-dataframes?noredirect=1#comment104618006_59197109 - verojoucla
请遵循pault在那个问题上的评论。你的答案已经被回答了。 - pissall
谢谢您的回答,我提出了一个新问题,但是为了查看我的解决方案,您能否请看一下?我只想在每个数据帧中创建一个包含单调递增ID的新列,请看一下 https://stackoverflow.com/questions/59211575/how-to-find-an-optimized-join-between-2-different-dataframes-in-spark - verojoucla
你对这个问题有什么想法吗? https://stackoverflow.com/questions/59931770/sum-of-column-values-pyspark 谢谢 - verojoucla
非常好的回答,谢谢!关于动态回答,*代表什么意思? - ocean800
1
@ocean800 它解开了我们在方括号中创建的列表。 - undefined

3
这里有一种通用/动态的方法来实现这个,而不是手动拼接它。我们只需要指定需要拼接的列即可。
# Importing requisite functions.
from pyspark.sql.functions import col, udf

# Creating the DataFrame
df = spark.createDataFrame([(1,12,34,67),(2,45,78,90),(3,23,93,56)],['id','column_1','column_2','column_3'])

现在,我们需要指定要连接的列列表,用-分隔。
list_of_columns_to_join = ['column_1','column_2','column_3']

最后,创建一个UDF。请注意,基于UDF的解决方案在性能上隐含地较慢。

def concat_cols(*list_cols):
    return '-'.join(list([str(i) for i in list_cols]))

concat_cols = udf(concat_cols)
df = df.withColumn('column_join', concat_cols(*list_of_columns_to_join))
df.show()
+---+--------+--------+--------+-----------+
| id|column_1|column_2|column_3|column_join|
+---+--------+--------+--------+-----------+
|  1|      12|      34|      67|   12-34-67|
|  2|      45|      78|      90|   45-78-90|
|  3|      23|      93|      56|   23-93-56|
+---+--------+--------+--------+-----------+

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接