当前位置: 首页 > 知识库问答 >
问题:

根据第一个字符的外观分隔字符串列

强承望
2023-03-14

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

我准备了一个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
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

共有1个答案

孔逸春
2023-03-14

我认为这里最好的选择是使用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非常简单-可以使用pyspark.sql.functions.split()在下划线上拆分字符串,然后使用getitem(0)获取拆分列表的第一个元素。

对于code部分,在下划线上拆分city并使用pyspark.sql.functions.posexpode()分解结果数组。然后筛选出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()
 类似资料:
  • 我希望能够根据子字符串分隔符拆分字符串,在分隔符子字符串的第一个字符之前开始拆分。现在: 将给我,但我希望得到

  • 如何将过滤器列表拆分为单个过滤器元件?split2String在线程“main”java.util.regex中导致:异常。PatternSyntaxException:索引10或(|和)附近的未闭合组(

  • 问题内容: 有人知道是否有基于固态库的方法来实现以下目的。 说我有琴弦 我想根据逗号分隔符将其解析为2个字符串。 我希望字符串看起来像这样: 有任何想法吗? 问题答案:

  • 我正在处理一个关于codingbat的问题,这个问题说:给定一个字符串和第二个“单词”字符串,我们会说这个单词匹配字符串,如果它出现在字符串的前面,除了它的第一个字符不需要完全匹配...在匹配时,返回字符串的前面,或以其他方式返回空字符串。所以,所以用字符串“河马”,“嗨”这个词返回“嗨”,“xip”返回“臀部”。单词长度至少为1。我不能解决它,但在网上找到了一个解决方案,代码如下所示。代码工作,

  • 问题内容: 我想删除字符串的第一个字符。 例如,我的字符串以a开头,而我只想删除它。字符串中有几次不应删除。 我正在用Python编写代码。 问题答案: python 2.x python 3.x 两张画

  • 问题内容: 我有一个值为的字符串。我想将字符串分成两个字符串,值为的字符串和的值为字符串。 正确的功能/语法是什么? 我已经看过了,但是找不到将数据返回到两个单独的字符串中的实际语法。 问题答案: 该功能适用于: