Pyspark 带子字符串的Pypark alter列
Pyspark n00b。。。如何用列本身的子字符串替换列?我正在尝试从字符串的开头和结尾删除选定数量的字符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
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
对象中添加(或减去)数字。我们需要首先将该数字转换为列
列
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 ]
)