如何在Pyspark dataframe中使用length split和MaxSplit拆分列?

如何在Pyspark dataframe中使用length split和MaxSplit拆分列?,pyspark,apache-spark-sql,pyspark-dataframes,Pyspark,Apache Spark Sql,Pyspark Dataframes,比如说 如果我在Pyspark中调用并显示CSV,得到如下列 +--------+ | Names| +--------+ |Rahul | |Ravi | |Raghu | |Romeo | +--------+ 如果我在我的函数中指定 长度=2 Maxsplit=3 然后我必须得到结果 +----------+-----------+----------+ |Col_1 |Col_2 |Col_3 | +----------+--------

比如说

如果我在Pyspark中调用并显示CSV,得到如下列

+--------+
|   Names|
+--------+
|Rahul   |
|Ravi    |
|Raghu   |
|Romeo   |
+--------+
如果我在我的函数中指定

长度=2 Maxsplit=3

然后我必须得到结果

+----------+-----------+----------+
|Col_1     |Col_2      |Col_3     |
+----------+-----------+----------+
|      Ra  |      hu   |    l     |
|      Ra  |      vi   |    Null  |
|      Ra  |      gh   |    u     |
|      Ro  |      me   |    o     |
+----------+-----------+----------+
类似于Pypark

+--------+
|   Names|
+--------+
|Rahul   |
|Ravi    |
|Raghu   |
|Romeo   |
+--------+
长度=3 Max split=2它应该为我提供如下输出

+----------+-----------+
|Col_1     |Col_2      |
+----------+-----------+
|      Rah |      ul   |
|      Rav |      i    |
|      Rag |      hu   |
|      Rom |      eo   |
+----------+-----------+
应该是这样的,谢谢你试试这个

import pyspark.sql.functions as F
tst = sqlContext.createDataFrame([("Raghu",1),("Ravi",2),("Rahul",3)],schema=["Name","val"])
def fn (split,max_n,tst):
    for i in range(max_n):
        tst_loop=tst.withColumn("coln"+str(i),F.substring(F.col("Name"),(i*split)+1,split))
        tst=tst_loop
    return(tst)
tst_res = fn(3,2,tst)
for循环也可以用列表理解或reduce代替,但我觉得在你的例子中,for循环看起来更整洁。不管怎样,他们有相同的身体计划

结果

+-----+---+-----+-----+
| Name|val|coln0|coln1|
+-----+---+-----+-----+
|Raghu|  1|  Rag|   hu|
| Ravi|  2|  Rav|    i|
|Rahul|  3|  Rah|   ul|
+-----+---+-----+-----+
试试这个

import pyspark.sql.functions as F
tst = sqlContext.createDataFrame([("Raghu",1),("Ravi",2),("Rahul",3)],schema=["Name","val"])
def fn (split,max_n,tst):
    for i in range(max_n):
        tst_loop=tst.withColumn("coln"+str(i),F.substring(F.col("Name"),(i*split)+1,split))
        tst=tst_loop
    return(tst)
tst_res = fn(3,2,tst)
for循环也可以用列表理解或reduce代替,但我觉得在你的例子中,for循环看起来更整洁。不管怎样,他们有相同的身体计划

结果

+-----+---+-----+-----+
| Name|val|coln0|coln1|
+-----+---+-----+-----+
|Raghu|  1|  Rag|   hu|
| Ravi|  2|  Rav|    i|
|Rahul|  3|  Rah|   ul|
+-----+---+-----+-----+
试试这个

def split(data,length,maxSplit):
    start=1
    for i in range(0,maxSplit):
        data = data.withColumn(f'col_{start}-{start+length-1}',f.substring('channel',start,length))
        start=length+1
    return data

df = split(data,3,2)        
df.show()
+--------+----+-------+-------+
| channel|type|col_1-3|col_4-6|
+--------+----+-------+-------+
|     web|   0|    web|       |
|     web|   1|    web|       |
|     web|   2|    web|       |
| twitter|   0|    twi|    tte|
| twitter|   1|    twi|    tte|
|facebook|   0|    fac|    ebo|
|facebook|   1|    fac|    ebo|
|facebook|   2|    fac|    ebo|
+--------+----+-------+-------+
试试这个

def split(data,length,maxSplit):
    start=1
    for i in range(0,maxSplit):
        data = data.withColumn(f'col_{start}-{start+length-1}',f.substring('channel',start,length))
        start=length+1
    return data

df = split(data,3,2)        
df.show()
+--------+----+-------+-------+
| channel|type|col_1-3|col_4-6|
+--------+----+-------+-------+
|     web|   0|    web|       |
|     web|   1|    web|       |
|     web|   2|    web|       |
| twitter|   0|    twi|    tte|
| twitter|   1|    twi|    tte|
|facebook|   0|    fac|    ebo|
|facebook|   1|    fac|    ebo|
|facebook|   2|    fac|    ebo|
+--------+----+-------+-------+

也许这是有用的-

加载测试数据 注:用scala编写

val长度=2 val Maxsplit=3 val df=SeqRahul、Ravi、Raghu、Romeo.toDFNames df.showfalse /** * +---+ *|姓名| * +---+ *|拉胡尔| *|拉维| *|拉古| *|罗密欧| * +---+ */ 根据长度和偏移量拆分字符串列 val schema=StructTypeRange1,maxslit+1.mapf=>StructFieldsCol\uUf,StringType val split=udfstr:String,length:Int,maxslit:Int=>{ val splits=str.toCharArray.groupedlength.map_u2;.mkString.toArray RowFactory.CreateSpits++Array.fillmaxSplit-splits.lengthnull:_* },模式 valp=df .withColumnx,拆分$Names,litLength,litMaxsplit 。选择Exprx* p、 秀假 p、 打印模式 /** * +---+---+---+ *|第1列|第2列|第3列| * +---+---+---+ *| Ra | hu | l| *| Ra | vi |空| *| Ra | gh | u| *| Ro | me | o| * +---+---+---+ * *根 *|-Col_1:string nullable=true *|-Col_2:string nullable=true *|-Col_3:string nullable=true */ 数据集[行]->数据集[数组[字符串]] val x=df.mapr=>{ val splits=r.getString0.ToCharray.groupedLength.map_ux0.mkString.toArray splits++Array.fillMaxsplit-splits.lengthnull } x、 秀假 x、 打印模式 /** * +------+ *|价值| * +------+ *|[Ra,hu,l]| *|[Ra,vi,]| *|[Ra,gh,u]| *|[罗,我,欧]| * +------+ * *根 *|-value:array nullable=true *| |-元素:string containsnall=true */
也许这是有用的-

加载测试数据 注:用scala编写

val长度=2 val Maxsplit=3 val df=SeqRahul、Ravi、Raghu、Romeo.toDFNames df.showfalse /** * +---+ *|姓名| * +---+ *|拉胡尔| *|拉维| *|拉古| *|罗密欧| * +---+ */ 根据长度和偏移量拆分字符串列 val schema=StructTypeRange1,maxslit+1.mapf=>StructFieldsCol\uUf,StringType val split=udfstr:String,length:Int,maxslit:Int=>{ val splits=str.toCharArray.groupedlength.map_u2;.mkString.toArray RowFactory.CreateSpits++Array.fillmaxSplit-splits.lengthnull:_* },模式 valp=df .withColumnx,拆分$Names,litLength,litMaxsplit 。选择Exprx* p、 秀假 p、 打印模式 /** * +---+---+---+ *|第1列|第2列|第3列| * +---+---+---+ *| Ra | hu | l| *| Ra | vi |空| *| Ra | gh | u| *| Ro | me | o| * +---+---+---+ * *根 *|-Col_1:string nullable=true *|-Col_2:string nullable=true *|-Col_3:string nullable=true */ 数据集[行]->数据集[数组[字符串]] val x=df.mapr=>{ val splits=r.getString0.ToCharray.groupedLength.map_ux0.mkString.toArray splits++Array.fillMaxsplit-splits.lengthnull } x、 秀假 x、 打印模式 /** * +------+ *|价值| * +------+ *|[Ra,hu,l]| *|[Ra,vi,]| *|[Ra,gh,u]| *|[罗,我,欧]| * +------+ * *根 *|-value:array nullable=true *| |-元素:string containsnall=true */
另一种方法。应该比任何循环或udf解决方案都快

from pyspark.sql import functions as F

def split(df,length,maxsplit):
    return df.withColumn('Names',F.split("Names","(?<=\\G{})".format('.'*length)))\
               .select(*((F.col("Names")[x]).alias("Col_"+str(x+1)) for x in range(0,maxsplit)))
  
split(df,3,2).show()

#+-----+-----+
#|Col_1|Col_2|
#+-----+-----+
#|  Rah|   ul|
#|  Rav|    i|
#|  Rag|   hu|
#|  Rom|   eo|
#+-----+-----+

split(df,2,3).show()

#+-----+-----+-----+
#|col_1|col_2|col_3|
#+-----+-----+-----+
#|   Ra|   hu|    l|
#|   Ra|   vi|     |
#|   Ra|   gh|    u|
#|   Ro|   me|    o|
#+-----+-----+-----+

另一种方法。应该比任何循环或udf解决方案都快

from pyspark.sql import functions as F

def split(df,length,maxsplit):
    return df.withColumn('Names',F.split("Names","(?<=\\G{})".format('.'*length)))\
               .select(*((F.col("Names")[x]).alias("Col_"+str(x+1)) for x in range(0,maxsplit)))
  
split(df,3,2).show()

#+-----+-----+
#|Col_1|Col_2|
#+-----+-----+
#|  Rah|   ul|
#|  Rav|    i|
#|  Rag|   hu|
#|  Rom|   eo|
#+-----+-----+

split(df,2,3).show()

#+-----+-----+-----+
#|col_1|col_2|col_3|
#+-----+-----+-----+
#|   Ra|   hu|    l|
#|   Ra|   vi|     |
#|   Ra|   gh|    u|
#|   Ro|   me|    o|
#+-----+-----+-----+

非常感谢,Someshwar Kale代码写得非常好Someshwar Kale,我跟踪了你写得非常好的代码,但基本上我需要用绝对Pyspark编写代码,但Scala也很好,可以理解两者之间没有太多变化。我非常感谢你的工作Someshwar KaleThanks,Someshwar Kale代码写得非常好Someshwar Kale,我跟踪了您编写的代码,它工作得非常好,但基本上我需要用绝对Pyspark编写代码,但是Scala I

我真的很感激你的工作Someshwar KaleThanks很多,Shubham Jain很有帮助我真的很感激你写的代码Shubham Jain,写得很漂亮这是我脑海中的输出,这是我所期望的,好逻辑的兄弟,保持乐观,Shubham Jain很有帮助我真的很欣赏你写的代码Shubham Jain,写得很漂亮这是我脑海中的输出,这是我所期望的,好的逻辑兄弟,保持它向上谢谢很多,Raghu很有帮助Raghu写得很漂亮,我真的很感谢你的努力和逻辑很高兴听到。你能不能也投票给我答案,这是常见的社区实践Raghu,你的代码绝对值得一提,Raghu写得很好,Raghu很有帮助,我真的很感谢你的努力,很高兴听到你这么说。你能不能也向上投票答案,这是常见的社区实践Ure Raghu,你的代码绝对值得向上投票绝对奇妙,完全如预期的murtihash,你的逻辑是完美的感谢很多,murtihash很乐意帮助,如果你想要Null而不是仅仅附加,那么输出中的空单元格将是一个空字符串,结尾处没有绝对奇妙,完全如预期的murtihash,您的逻辑是完美的非常感谢,murtihash很高兴提供帮助,如果您希望Null而不是仅附加,则输出中的空单元格将是空字符串。替换,结尾处没有