Apache spark 如何在ApacheSpark中基于分隔符将单个字符串列转换为多个列
我有一个带有字符串列的数据框,我想从中创建多个列 这是我的输入数据,Apache spark 如何在ApacheSpark中基于分隔符将单个字符串列转换为多个列,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,我有一个带有字符串列的数据框,我想从中创建多个列 这是我的输入数据,pagename是我的字符串列 我想从中创建多个列。字符串的格式相同-col1:value1 col2:value2 col3:value3。。。colN:valueN。在输出中,我需要多个列-col1到colN,每个列的值作为行。这是输出- 我怎样才能在spark中做到这一点?Scala或Python对我来说都很好。下面的代码创建输入数据帧- scala> val df = spark.sql(s"&quo
pagename
是我的字符串列
我想从中创建多个列。字符串的格式相同-col1:value1 col2:value2 col3:value3。。。colN:valueN
。在输出中,我需要多个列-col1到colN
,每个列的值作为行。这是输出-
我怎样才能在spark中做到这一点?Scala或Python对我来说都很好。下面的代码创建输入数据帧-
scala> val df = spark.sql(s"""select 1 as id, "a:100 b:500 c:200" as pagename union select 2 as id, "a:101 b:501 c:201" as pagename """)
df: org.apache.spark.sql.DataFrame = [id: int, pagename: string]
scala> df.show(false)
+---+-----------------+
|id |pagename |
+---+-----------------+
|2 |a:101 b:501 c:201|
|1 |a:100 b:500 c:200|
+---+-----------------+
scala> df.printSchema
root
|-- id: integer (nullable = false)
|-- pagename: string (nullable = false)
注意-该示例仅显示了3列,但一般来说,我有100多列需要处理。因此,我立即想到了两个选项 分隔符 您有一些明显的分隔符,可以根据这些分隔符进行拆分。为此,请使用
split
功能
从pyspark.sql导入函数为F
分隔符=“:”
df=df.withColumn(
“拆分_列”,
F.split(F.col(“pagename”),分隔符)
)
#“split_column”现在是一个数组,所以我们需要从数组中取出项目
df=df.withColumn(
“a”,
F.col(“拆分列”).getItem(0)
)
这并不理想,因为您仍然需要执行一些字符串操作来删除空格,然后执行int转换器——但这很容易应用于多个列
正则表达式
由于格式非常固定,您可以使用正则表达式执行相同的操作
重新导入
regex_pattern=r“a\:()b\:()c\:()”
匹配组=[“a”、“b”、“c”]
对于范围内的i(重新编译(regex_模式).groups):
df=df.withColumn(
匹配组[i],
F.regexp_extract(F.col(pagename),regex_模式,i+1),
)
警告:在尝试运行任何东西之前,请检查正则表达式(因为我手边没有编辑器),因此立即想到两个选项 分隔符 您有一些明显的分隔符,可以根据这些分隔符进行拆分。为此,请使用
split
功能
从pyspark.sql导入函数为F
分隔符=“:”
df=df.withColumn(
“拆分_列”,
F.split(F.col(“pagename”),分隔符)
)
#“split_column”现在是一个数组,所以我们需要从数组中取出项目
df=df.withColumn(
“a”,
F.col(“拆分列”).getItem(0)
)
这并不理想,因为您仍然需要执行一些字符串操作来删除空格,然后执行int转换器——但这很容易应用于多个列
正则表达式
由于格式非常固定,您可以使用正则表达式执行相同的操作
重新导入
regex_pattern=r“a\:()b\:()c\:()”
匹配组=[“a”、“b”、“c”]
对于范围内的i(重新编译(regex_模式).groups):
df=df.withColumn(
匹配组[i],
F.regexp_extract(F.col(pagename),regex_模式,i+1),
)
警告:在尝试运行任何东西之前,请检查正则表达式(因为我手头没有编辑器)您可以使用
str\u to\u map
,分解生成的映射并旋转:
val df2 = df.select(
col("id"),
expr("explode(str_to_map(pagename, ' ', ':'))")
).groupBy("id").pivot("key").agg(first("value"))
df2.show
+---+---+---+---+
| id| a| b| c|
+---+---+---+---+
| 1|100|500|200|
| 2|101|501|201|
+---+---+---+---+
您可以使用
str\u to\u map
,分解生成的贴图和轴:
val df2 = df.select(
col("id"),
expr("explode(str_to_map(pagename, ' ', ':'))")
).groupBy("id").pivot("key").agg(first("value"))
df2.show
+---+---+---+---+
| id| a| b| c|
+---+---+---+---+
| 1|100|500|200|
| 2|101|501|201|
+---+---+---+---+
你已经标记了
pyspark
,所以我用Python回复了,但是要点在scala中是一样的你标记了pyspark
,所以我用Python回复了,但是要点在scala中是一样的,我们可以将a,b,c列中的数字转换成我们想要的任何数据类型吗?例如,现在输出显示为string
,但我可能需要这些列,如int
、float
等。您可以根据需要在agg
中强制转换,例如agg(第一个(“值”)。强制转换(“int”)
是str_to_map()
build-in-function?在SQL API中可用,但在scala/Python中不可用如果我想在多个列中应用此函数,那么获取数据的最佳方法是什么?例如,如果有pagename
列和pagename1
列都有这样的分隔数据,那么输出列的数量将是id、a、b、c、a1、b1、c1
,其中a1、b1、c1
列中存在pagename1
。行数相同,但列应扩展到列之外。我们能否将列a、b、c
中的数字转换为我们需要的任何数据类型?例如,现在输出显示为string
,但我可能需要这些列,如int
、float
等。您可以根据需要在agg
中强制转换,例如agg(第一个(“值”)。强制转换(“int”)
是str_to_map()
build-in-function?在SQL API中可用,但在scala/Python中不可用如果我想在多个列中应用此函数,那么获取数据的最佳方法是什么?例如,如果有pagename
列和pagename1
列都有这样的分隔数据,那么输出列的数量将是id、a、b、c、a1、b1、c1
,其中a1、b1、c1
列中存在pagename1
。行数相同,但列应向外扩展