有限制的子字符串 (pyspark.sql.Column.substr)

Posted

技术标签:

【中文标题】有限制的子字符串 (pyspark.sql.Column.substr)【英文标题】:Substring (pyspark.sql.Column.substr) with restrictions 【发布时间】:2018-03-22 15:46:34 【问题描述】:

我有一个代码,例如 C78907。我要拆分:

C78     # level 1
C789    # Level2
C7890   # Level 3
C78907  # Level 4

到目前为止我正在使用什么:

Df3 = Df2.withColumn('Level_One', concat(Df2.code.substr(1, 3)))
Df4 = Df3.withColumn('Level_two', concat(Df3.code.substr(1, 4)))
Df5 = Df4.withColumn('Level_theree', concat(Df4.code.substr(1, 5)))
Df6 = Df5.withColumn('Level_four', concat(Df5.code.substr(1, 6)))

问题是在查看结果时,第四级的代码(应该是 6 个组件)可能包含第一级或第二级或第三级的代码。

721 7213    7213    7213
758 7580    7580    7580
724 7242    7242    7242
737 7373    73730   73730
789 7895    78959   78959
V06 V061    V061    V061
381 3810    38100   38100

理想情况下,限制可能是有用的。我的意思是:

对于 1 级,仅保留 3 个组件。 适用于 2 级 4 级组件,不少于。 适用于 3 级 5 级组件且不少于。 适用于 4 级 6 级组件,不少于。 如果所需数量的组件不存在,则输入null,而不是与前一个插补。

想要的输出:

Initial_code   level1  level2   level3   level4        
 7213           721    7213     null      null
 7580           758    7580     null      null
 7242           724    7242     null      null
 73730          737    7373     73730     null
 38100D         381    3810     38100     38100D

【问题讨论】:

你想要的输出是什么?你可以edit你的问题并添加它吗?如果您还可以提供一个示例数据框,这也会很有帮助:how to create good reproducible apache spark dataframe examples。 【参考方案1】:

您可以使用pyspark.sql.Column.when()pyspark.sql.functions.length() 来实现所需的输出。创建列时,检查子字符串的长度是否正确。如果没有,请使用pyspark.sql.functions.lit() 将该列设置为None

例如:

import pyspark.sql.functions as f
df.withColumn('Level_One', f.when(
        f.length(f.col('code').substr(1, 3)) == 3,
        f.col('code').substr(1, 3)
    ).otherwise(f.lit(None)))\
    .withColumn('Level_Two', f.when(
        f.length(f.col('code').substr(1, 4)) == 4,
        f.col('code').substr(1, 4)
    ).otherwise(f.lit(None)))\
    .withColumn('Level_Three', f.when(
        f.length(f.col('code').substr(1, 5)) == 5,
        f.col('code').substr(1, 5)
    ).otherwise(f.lit(None)))\
    .withColumn('Level_Four', f.when(
        f.length(f.col('code').substr(1, 6)) == 6,
        f.col('code').substr(1, 6)
    ).otherwise(f.lit(None)))\
    .show()

输出:

+------+---------+---------+-----------+----------+
|  Code|Level_One|Level_Two|Level_Three|Level_Four|
+------+---------+---------+-----------+----------+
|  7213|      721|     7213|       null|      null|
|  7580|      758|     7580|       null|      null|
|  7242|      724|     7242|       null|      null|
| 73730|      737|     7373|      73730|      null|
|38100D|      381|     3810|      38100|    38100D|
+------+---------+---------+-----------+----------+

【讨论】:

说明:这里不需要otherwise(f.lit(None)),因为如果不满足条件,when 将默认返回null

以上是关于有限制的子字符串 (pyspark.sql.Column.substr)的主要内容,如果未能解决你的问题,请参考以下文章

LMDB 中的子数据库有限制吗?

后缀自动机如何限制串长

hihoCoder1690 (动态规划)

限制反应组件中的子组件

51nod 1255 字典序最小的子序列

Bailian2744 子串