【问题标题】:remove last few characters in PySpark dataframe column删除 PySpark 数据框列中的最后几个字符
【发布时间】:2019-04-08 17:44:28
【问题描述】:

我有一个 PySpark 数据框。如何从下面的 name 列中截断/删除最后 5 个字符 -

from pyspark.sql.functions import substring, length
valuesCol = [('rose_2012',),('jasmine_2013',),('lily_2014',),('daffodil_2017',),('sunflower_2016',)]
df = sqlContext.createDataFrame(valuesCol,['name'])
df.show()

+--------------+
|          name|
+--------------+
|     rose_2012|
|  jasmine_2013|
|     lily_2014|
| daffodil_2017|
|sunflower_2016|
+--------------+

我想创建 2 列,floweryear 列。

预期输出:

+--------------+----+---------+
|          name|year|   flower|
+--------------+----+---------+
|     rose_2012|2012|     rose|
|  jasmine_2013|2013|  jasmine|
|     lily_2014|2014|     lily|
| daffodil_2017|2017| daffodil|
|sunflower_2016|2016|subflower|
+--------------+----+---------+

year 我创建的专栏 -

df = df.withColumn("year", substring(col("name"),-4,4))
df.show()
+--------------+----+
|          name|year|
+--------------+----+
|     rose_2012|2012|
|  jasmine_2013|2013|
|     lily_2014|2014|
| daffodil_2017|2017|
|sunflower_2016|2016|
+--------------+----+

我不知道怎么砍最后5个字符,所以我只有花的名字。我通过调用length 尝试了类似的方法,但这不起作用。

df = df.withColumn("flower",substring(col("name"),0,length(col("name"))-5))

如何创建只有花名的flower 列?

【问题讨论】:

    标签: python pyspark substring


    【解决方案1】:

    您可以使用split 函数。这段代码做你想做的事:

    import pyspark.sql.functions as f
    
    newDF = df.withColumn("year", f.split(df['name'], '\_')[1]).\
               withColumn("flower", f.split(df['name'], '\_')[0])
    
    newDF.show()
    
    +--------------+----+---------+
    |          name|year|   flower|
    +--------------+----+---------+
    |     rose_2012|2012|     rose|
    |  jasmine_2013|2013|  jasmine|
    |     lily_2014|2014|     lily|
    | daffodil_2017|2017| daffodil|
    |sunflower_2016|2016|sunflower|
    +--------------+----+---------+
    

    【讨论】:

    • 是否有必要像你所做的那样转义下划线\_?
    • “转义下划线”到底是什么意思?该函数将name列中的字符串拆分为两个字符串,一个在_之前,另一个在_之后,不管字符串的长度是多少。
    • 是的,我明白了,但是由于您也使用了反斜杠 \,所以认为您正在转义它?
    • 是的,你想的没错。顺便说一句,它也可以在没有反斜杠 \ 的情况下工作。
    【解决方案2】:

    你可以使用expr函数

    >>> from pyspark.sql.functions import substring, length, col, expr
    >>> df = df.withColumn("flower",expr("substring(name, 1, length(name)-5)"))
    >>> df.show()
    +--------------+----+---------+
    |          name|year|   flower|
    +--------------+----+---------+
    |     rose_2012|2012|     rose|
    |  jasmine_2013|2013|  jasmine|
    |     lily_2014|2014|     lily|
    | daffodil_2017|2017| daffodil|
    |sunflower_2016|2016|sunflower|
    +--------------+----+---------+
    

    【讨论】:

    • 这正是我在寻找的东西,通过调用长度,但无法弄清楚。非常感谢阿里。
    【解决方案3】:

    在这种情况下,由于我们要提取字母字符,所以 REGEX 也可以工作。

    from pyspark.sql.functions import regexp_extract 
    df = df.withColumn("flower",regexp_extract(df['name'], '[a-zA-Z]+',0))
    df.show()
    +--------------+----+---------+
    |          name|year|   flower|
    +--------------+----+---------+
    |     rose_2012|2012|     rose|
    |  jasmine_2013|2013|  jasmine|
    |     lily_2014|2014|     lily|
    | daffodil_2017|2017| daffodil|
    |sunflower_2016|2016|sunflower|
    +--------------+----+---------+
    

    【讨论】:

      【解决方案4】:

      添加少许调整以避免硬编码并使用instr 函数通过下划线('_') 的位置动态识别列长度。

      df = spark.createDataFrame([('rose_2012',),('jasmine_2013',),('lily_2014',),('daffodil_2017',),('sunflower_2016',)],['name'])
      
      
      df.withColumn("flower",expr("substr(name, 1, (instr(name,'_')-1) )")).\
              withColumn("year",expr("substr(name, (instr(name,'_')+1),length(name))")).show()
      

      【讨论】:

        猜你喜欢
        • 2022-06-13
        • 1970-01-01
        • 2011-06-25
        • 2020-05-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多