代码之家  ›  专栏  ›  技术社区  ›  Sotos

如果找到分隔符,则拆分字符串

  •  1
  • Sotos  · 技术社区  · 6 年前

    考虑以下数据帧,

    cols = ['Id', 'col1', 'col2', 'col3']
    vals = [('1A','Not his side|:|This side', 'This side', 'Not this either|:|but this'),  
            ('1B','Keep this', 'This one|:|keep this', 'remove|:|keep that')]
    
    dd1 = sqlContext.createDataFrame(vals, cols)
    
    #+---+------------------------+--------------------+--------------------------+
    #|Id |col1                    |col2                |col3                      |
    #+---+------------------------+--------------------+--------------------------+
    #|1A |Not his side|:|This side|This side           |Not this either|:|but this|
    #|1B |Keep this               |This one|:|keep this|remove|:|keep that        |
    #+---+------------------------+--------------------+--------------------------+
    

    我要做的是 |:| 并保留第二个词。但是,如果字符串不包含分隔符( > ),然后我得到 null , 即。:

    users1 = [F.split(F.col(x), "\\|:\\|").alias(x) for x in cols]
    dd1.select(*users1).show()
    
    #+---------+---------+---------+
    #|     col1|     col2|     col3|
    #+---------+---------+---------+
    #|This side|     null| but this|
    #|     null|keep this|keep that|
    #+---------+---------+---------+
    

    我要找的结果是:

    +---+---------+---------+---------+
    |Id |col1     |col2     |col3     |
    +---+---------+---------+---------+
    |1A |This side|This side|but this |
    |1B |Keep this|keep this|keep that|
    +---+---------+---------+---------+
    
    3 回复  |  直到 6 年前
        1
  •  2
  •   Shaido Aman    6 年前

    使用 when otherwise 并检查字符串是否包含 "|:|" . 具体操作如下:

    cols = ['col1', 'col2', 'col3']
    
    users1 = [F.when(F.col(x).contains("|:|"), F.split(F.col(x), "\\|:\\|")[1]).otherwise(F.col(x)).alias(x) for x in cols]
    dd1.select(F.col('Id'), *users1)
    

    这里 cols 只包括要拆分的列。决赛 select 将包括 Id 也列。

        2
  •  1
  •   Ramesh Maharjan    6 年前

    你可以使用 when size 内置功能

    users1 = [F.when(F.size(F.split(F.col(x), "\\|:\\|")) > 1, F.split(F.col(x), "\\|:\\|")[1]).otherwise(F.col(x)).alias(x) for x in cols]
    dd1.select(*users1).show()
    

    它应该给你

    +---+---------+---------+---------+
    | Id|     col1|     col2|     col3|
    +---+---------+---------+---------+
    | 1A|This side|This side| but this|
    | 1B|Keep this|keep this|keep that|
    +---+---------+---------+---------+
    

    您可以修改答案以便使用 split 只起一次作用。

    我希望答案是有帮助的,应该是一个很好的提示如何进行。

        3
  •  1
  •   Oli    6 年前

    您在问题中定义的选择不会产生您提到的结果。我想你忘了从数组中选择元素;)

    users1 = [F.split(F.col(x), "\\|:\\|").alias(x) for x in cols]
    dd1.select(*users1).show()
    +----+--------------------+--------------------+--------------------+
    |  Id|                col1|                col2|                col3|
    +----+--------------------+--------------------+--------------------+
    |[1A]|[Not his side, Th...|         [This side]|[Not this either,...|
    |[1B]|         [Keep this]|[This one, keep t...| [remove, keep that]|
    +----+--------------------+--------------------+--------------------+
    

    要实现所需,只需选择数组的最后一个元素。您可以使用size函数执行以下操作:

    users2 = [F.col(x).getItem(F.size(F.col(x))-1).alias(x) for x in cols]
    dd1.select(*users1).select(*users2).show()
    +---+---------+---------+---------+
    | Id|     col1|     col2|     col3|
    +---+---------+---------+---------+
    | 1A|This side|This side| but this|
    | 1B|Keep this|keep this|keep that|
    +---+---------+---------+---------+