【问题标题】:create new pyspark dataframe columns by splitting values on white space [duplicate]通过在空白处拆分值来创建新的 pyspark 数据框列 [重复]
【发布时间】:2020-07-05 13:54:16
【问题描述】:

我有一个 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         |             |
+------+-------------------+-------------+-------------+-------------+

【问题讨论】:

  • 我们可以假设您只需要多三列吗?(1,2,3) 或者根据产品名称可以有更多吗?

标签: python pyspark pyspark-sql pyspark-dataframes


【解决方案1】:

Split 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|        |
#+------+-------------------+--------+--------+--------+

To do more dynamic way:

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|        |
#+------+-------------------+--------+--------+--------+

【讨论】:

  • 谢谢,我喜欢动态版。我确实必须使用 orderBy 将部分编辑为“.orderBy("size",ascending=False)"。我不知道这是否与我使用的 pyspark 版本有关。
  • @user3476463, .orderBy(desc("size")) 也在做同样的事情......就像我们按降序排列一样!
【解决方案2】:

您可以使用splitelement_atwhen/otherwise 子句与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    |        |        |
+------+-------------------+--------+--------+--------+

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-02
    • 2013-06-01
    • 1970-01-01
    相关资源
    最近更新 更多