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

通过在空白区域拆分值来创建新的pyspark dataframe列[重复]

易祖鹤
2023-03-14

我有一个像下面的输入数据一样的pyspark数据框架。我想在空白上拆分productname列中的值。然后我想用前3个值创建新列。我在下面有示例输入和输出数据。有人能建议如何使用pyspark做到这一点吗?

输入数据:

+------+-------------------+
|id    |productname        |
+------+-------------------+
|235832|EXTREME BERRY Sweet|             
|419736|BLUE CHASER SAUCE  |             
|124513|LAAVA C2L5         |
+------+-------------------+

输出:

+------+-------------------+-------------+-------------+-------------+
|id    |productname        |product1     |product2     |product3     |
+------+-------------------+-------------+-------------+-------------+
|235832|EXTREME BERRY Sweet|EXTREME      |BERRY        |Sweet        |
|419736|BLUE CHASER SAUCE  |BLUE         |CHASER       |SAUCE        |
|124513|LAAVA C2L5         |LAAVA        |C2L5         |             |
+------+-------------------+-------------+-------------+-------------+

共有2个答案

孙佐
2023-03-14

您可以使用<code>split</code>、<code>element_at</code>和<code>when/other</code>子句以及<code>array_union

from pyspark.sql import functions as F
from pyspark.sql.functions import when
df.withColumn("array", F.split("productname","\ "))\
  .withColumn("array", F.when(F.size("array")==2, F.array_union(F.col("array"),F.array(F.lit(""))))\
                        .when(F.size("array")==1, F.array_union(F.col("array"),F.array(F.lit(" "),F.lit(""))))\
                        .otherwise(F.col("array")))\
  .withColumn("product1", F.element_at("array",1))\
  .withColumn("product2", F.element_at("array",2))\
  .withColumn("product3", F.element_at("array",3)).drop("array")\
  .show(truncate=False)

+------+-------------------+--------+--------+--------+
|id    |productname        |product1|product2|product3|
+------+-------------------+--------+--------+--------+
|235832|EXTREME BERRY Sweet|EXTREME |BERRY   |Sweet   |
|419736|BLUE CHASER SAUCE  |BLUE    |CHASER  |SAUCE   |
|124513|LAAVA C2L5         |LAAVA   |C2L5    |        |
|123455|LAVA               |LAVA    |        |        |
+------+-------------------+--------+--------+--------+
扈德容
2023-03-14

拆分productname列,然后使用element_at(或创建新列。索引值上的getItem()

df.withColumn("tmp",split(col("productname"),"\s+")).\
withColumn("product1",element_at(col("tmp"),1)).\
withColumn("product2",element_at(col("tmp"),2)).\
withColumn("product3",coalesce(element_at(col("tmp"),3),lit(""))).drop("tmp").show()

#or

df.withColumn("tmp",split(col("productname"),"\s+")).\
withColumn("product1",col("tmp").getItem(0)).\
withColumn("product2",col("tmp").getItem(1)).\
withColumn("product3",coalesce(col("tmp").getItem(2),lit(""))).drop("tmp").show()
#+------+-------------------+--------+--------+--------+
#|    id|        productname|product1|product2|product3|
#+------+-------------------+--------+--------+--------+
#|235832|EXTREME BERRY Sweet| EXTREME|   BERRY|   Sweet|
#|     4|  BLUE CHASER SAUCE|    BLUE|  CHASER|   SAUCE|
#|     1|         LAAVA C2L5|   LAAVA|    C2L5|        |
#+------+-------------------+--------+--------+--------+

< code >做更动态的方式:

df.show()
#+------+-------------------+
#|    id|        productname|
#+------+-------------------+
#|235832|EXTREME BERRY Sweet|
#|     4|  BLUE CHASER SAUCE|
#|     1|         LAAVA C2L5|
#+------+-------------------+
#caluculate array max size and store into variable
arr=int(df.select(size(split(col("productname"),"\s+")).alias("size")).orderBy(desc("size")).collect()[0][0])

#loop through arr variable and add the columns replace null with ""
(df.withColumn('temp', split('productname', '\s+')).select("*",*(coalesce(col('temp').getItem(i),lit("")).alias('product{}'.format(i+1)) for i in range(arr))).drop("temp").show())

#+------+-------------------+--------+--------+--------+
#|    id|        productname|product1|product2|product3|
#+------+-------------------+--------+--------+--------+
#|235832|EXTREME BERRY Sweet| EXTREME|   BERRY|   Sweet|
#|     4|  BLUE CHASER SAUCE|    BLUE|  CHASER|   SAUCE|
#|     1|         LAAVA C2L5|   LAAVA|    C2L5|        |
#+------+-------------------+--------+--------+--------+
 类似资料:
  • 假设我有一个1.2 GB的文件,那么考虑到128 MB的块大小,它将创建10个分区。现在,如果我将其重新分区(或合并)为4个分区,这意味着每个分区肯定会超过128 MB。在这种情况下,每个分区必须容纳320 MB的数据,但块大小是128 MB。我有点糊涂了。这怎么可能?我们如何创建一个大于块大小的分区?

  • 问题内容: 我正在尝试提出一个将更新的MySQL查询…我可以做这样的事情吗? 问题答案: 通过将单引号放在“点-5”周围,可以将该表达式转换为纯文本字符串。不用引号就可以使MySQL看到您正在引用一个字段(点),并从其当前值中减去5。

  • 在偶尔的情况下,你可能会想要保留那些与你的代码没有共同祖先的分支。例如在这些分支上保留生成的文档或者其他一些东西。如果你需要创建一个不使用当前代码库作为父提交的分支,你可以用如下的方法创建一个空分支: git symbolic-ref HEAD refs/heads/newbranch rm .git/index git clean -fdx <do work> git add your

  • 创建新的Arraylist(如第一种方法)与创建第二种方法之间的区别是什么?在创建一个时,您考虑了什么?

  • 所以我有一个列表: 对于每个匹配的数字,我必须获取标识符的每个排列。我需要从我的示例中获得的列表如下: 我目前正在采取的解决问题的步骤: < li >读入列表,将每个值放入一个数组([a][12]),然后将它放入一个ArrayList中 < li >然后我会查找是否有重复的数字,并在散列表中记录下来 < li >然后我设置了一个for循环来遍历HashMap。如果号码没有重复,我就把它加到名单上。

  • 我希望能够处理从必须在页面中访问的源读取的java流。作为第一种方法,我实现了一个分页迭代器,它在当前页面用尽条目时简单地请求页面,然后使用< code > stream support . stream(iterator,false)获取迭代器上的流句柄。 因为我发现获取我的页面非常昂贵,所以我想通过并行流的方式访问页面。此时,我发现由于java直接从迭代器提供的spliterator实现,我的