Pyspark 带子字符串的Pypark alter列

Pyspark 带子字符串的Pypark alter列,pyspark,pyspark-sql,Pyspark,Pyspark Sql,Pyspark n00b。。。如何用列本身的子字符串替换列?我正在尝试从字符串的开头和结尾删除选定数量的字符 from pyspark.sql.functions import substring import pandas as pd pdf = pd.DataFrame({'COLUMN_NAME':['_string_','_another string_']}) # this is what i'm looking for... pdf['COLUMN_NAME_fix']=pdf['C

Pyspark n00b。。。如何用列本身的子字符串替换列?我正在尝试从字符串的开头和结尾删除选定数量的字符

from pyspark.sql.functions import substring
import pandas as pd
pdf = pd.DataFrame({'COLUMN_NAME':['_string_','_another string_']})
# this is what i'm looking for...
pdf['COLUMN_NAME_fix']=pdf['COLUMN_NAME'].str[1:-1] 

df = sqlContext.createDataFrame(pdf)
# following not working... COLUMN_NAME_fix is blank
df.withColumn('COLUMN_NAME_fix', substring('COLUMN_NAME', 1, -1)).show() 
这是非常接近,但略有不同。还有这个

pyspark.sql.functions.substring(str、pos、len)

当str为字符串类型时,子字符串从pos开始,长度为len;当str为二进制类型时,返回字节数组中从pos开始的片段,长度为len

在代码中

df.withColumn('COLUMN_NAME_fix', substring('COLUMN_NAME', 1, -1))
1 is pos and -1 becomes len, length can't be -1 and so it returns null
试试这个(使用固定语法)

尝试:

其中1=字符串中的起始位置,以及
10=从起始位置(包括起始位置)包含的字符数

接受的答案使用一个
udf
(用户定义函数),该函数通常(远)比本机spark代码慢。Grant Shannon的答案确实使用了本机spark代码,但正如citynorman在评论中所指出的那样,对于可变字符串长度,这是如何工作的还不是100%清楚

使用本机spark代码(无自定义项)和可变字符串长度回答

从pyspark中的文档中,我们可以看到:startPos和length可以是
int
Column
类型(两者必须是相同的类型)。所以我们只需要创建一个包含字符串长度的列,并将其用作参数

import pyspark.sql.functions as F

result = (
    df
    .withColumn('length', F.length('COLUMN_NAME'))
    .withColumn('fixed_in_spark', F.col('COLUMN_NAME').substr(F.lit(2), F.col('length') - F.lit(2)))
)

# result:
+----------------+---------------+----+--------------+
|     COLUMN_NAME|COLUMN_NAME_fix|size|fixed_in_spark|
+----------------+---------------+----+--------------+
|        _string_|         string|   8|        string|
|_another string_| another string|  16|another string|
+----------------+---------------+----+--------------+
注:

  • 我们使用长度-2,因为我们从第二个字符开始(需要从第二个字符到最后一个字符)
  • 我们需要使用
    sf.lit
    ,因为我们不能向
    对象中添加(或减去)数字。我们需要首先将该数字转换为

如果目标是从列名中删除“\u”,那么我将使用列表理解:

df.select(
    [ col(c).alias(c.replace('_', '') ) for c in df.columns ]
)

如果长度是动态的怎么办?使用:df['COLUMN_NAME'].substr(startPos,strLength),其中startPos是可变的起始位置,strLength是要包含的字符数的可变长度。是的,如果样本之间发生
strLength
更改,则此操作失败,如上面的示例所示
import pyspark.sql.functions as F

result = (
    df
    .withColumn('length', F.length('COLUMN_NAME'))
    .withColumn('fixed_in_spark', F.col('COLUMN_NAME').substr(F.lit(2), F.col('length') - F.lit(2)))
)

# result:
+----------------+---------------+----+--------------+
|     COLUMN_NAME|COLUMN_NAME_fix|size|fixed_in_spark|
+----------------+---------------+----+--------------+
|        _string_|         string|   8|        string|
|_another string_| another string|  16|another string|
+----------------+---------------+----+--------------+
df.select(
    [ col(c).alias(c.replace('_', '') ) for c in df.columns ]
)