gpt4 book ai didi

python - 根据第一个字符的出现分隔字符串列

转载 作者:太空宇宙 更新时间:2023-11-04 00:13:56 25 4
gpt4 key购买 nike

我想根据字符的首次出现将 Spark DataFrame 的列分成 2 个不同的列,在本例中为下划线(“_”)。

我准备了一个 100% 可重现的例子:

模拟的 Spark DataFrame 是:

df = spark.createDataFrame(
[
(1, 1.8, 'newyork_3434_north'),
(4, 2.6, 'la_432432432_south'),
(6, 3.3, 'boston_234324_east'),
(8, 4.1, 'detroit_6757_west'),
(2, 5.7, 'miami_133123_north'),
(3, 6.2, 'atlanta_093394_west'),
(1, 6.1, 'houston_87342_east')
],
('ranking', "coordenate", "city")
)

上面的代码创建了一个如下表:

ranking  coordenate  city
1 1.8 newyork_3434_north
4 2.6 la_432432432_south
6 3.3 boston_234324_east
8 4.1 detroit_6757_west
2 5.7 miami_133123_north
3 6.2 atlanta_093394_west
1 6.1 houston_87342_east

我想做的是根据第一个下划线从左到右的位置将列 city 分成 2 个不同的列。

最终所需的表格将类似于:

ranking  coordenate  city       code
1 1.8 newyork 3434_north
4 2.6 la 432432432_south
6 3.3 boston 234324_east
8 4.1 detroit 6757_west
2 5.7 miami 133123_north
3 6.2 atlanta 093394_west
1 6.1 houston 87342_east

我看过几个关于这个主题的话题,但他们没有谈论字符的第一次出现( link_1link_2 等),而是按字符串中的所有特定字符拆分;或按字符串中字符的特定位置拆分。

我也尝试过 Python Pandas 方法,但正如预期的那样,通过扩展或类比,它不适用于 PySpark (link_3)

预先感谢您的帮助。

最佳答案

我认为这里最好的选择是使用 pyspark.sql.functions.regexp_extract()pyspark.sql.functions.regexp_replace():

import pyspark.sql.functions as f

df.select(
"ranking",
"coordenate",
f.regexp_extract("city", pattern="^[A-Za-z]+(?=_)", idx=0).alias('city'),
f.regexp_replace("city", "^[A-Za-z]+_", "").alias("code")
).show()
#+-------+----------+----------+---------------+
#|ranking|coordenate| city| code|
#+-------+----------+----------+---------------+
#| 1| 1.8| newyork| 3434_north|
#| 4| 2.6| la|432432432_south|
#| 6| 3.3| boston| 234324_east|
#| 8| 4.1| detroit| 6757_west|
#| 2| 5.7| miami| 133123_north|
#| 3| 6.2| atlanta| 093394_west|
#| 1| 6.1| houston| 87342_east|
#+-------+----------+----------+---------------+

在这两种情况下,模式本质上是相同的:

  • ^[A-Za-z]+:匹配从字符串开头开始的任意数量的字母
  • (?=_):下划线的正面前瞻

对于 city,我们找到这个模式并提取第一个匹配项。对于 code,我们将先行更改为匹配并将模式替换为空字符串。


如果很难找到合适的正则表达式模式,这里有一个适用于 Spark 2.1 及更高版本的替代方法:

获取 city 很简单 - 您可以使用 pyspark.sql.functions.split() 将字符串拆分为下划线,然后使用 getItem(0) 获取拆分列表的第一个元素。

对于 code 部分,将 city 拆分为下划线并使用 pyspark.sql.functions.posexplode() 分解结果数组.然后筛选出 pos > 0,按原始列分组,并使用 pyspark.sql.functions.concat_ws 加入收集到的标记。

df.select(
"*",
f.posexplode(f.split("city", "_")).alias("pos", "token")
)\
.where("pos > 0")\
.groupBy("ranking", "coordenate", "city")\
.agg(f.concat_ws("_" ,f.collect_list("token")).alias("code"))\
.select(
"ranking",
"coordenate",
f.split("city", "_").getItem(0).alias("city"),
"code"
)\
.show()

关于python - 根据第一个字符的出现分隔字符串列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51540331/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com