Python 具有条件序列的pyspark中的未编码

Python 具有条件序列的pyspark中的未编码,python,sql,dataframe,apache-spark,pyspark,Python,Sql,Dataframe,Apache Spark,Pyspark,我需要在数据帧pyspark中使用序列号conditional对列进行未编码。例如 输入数据帧 预期输出数据帧 您可以看到,当一行的c1=1时,该行将将c4列的内容拆分为新行(因为长度超过了限制)。否则,如果c1=0时,则c4包含完整内容,则无需拆分为新行c4列可以将其拆分为多行next pyspark中的这个pyspark.sql.functions.explode(col),我需要取消编码,但我有一个条件是c1列(这不是简单的,比如group by then COLLET listdf.

我需要在数据帧pyspark中使用序列号conditional对列进行未编码。例如

输入数据帧

预期输出数据帧

您可以看到,当一行的c1=1时,该行将将c4列的内容拆分为新行(因为长度超过了限制)。否则,如果c1=0时,则c4包含完整内容,则无需拆分为新行c4列可以将其拆分为多行next

pyspark中的这个pyspark.sql.functions.explode(col),我需要取消编码,但我有一个条件是c1列(这不是简单的,比如group by then COLLET listdf.groupby().agg(F.collect_list()),因为c1是序列条件)

我尝试通过本主题使用窗口函数流。但下一步如何解决c4 col中断多行的问题

示例代码

from pyspark.sql import SparkSession
spark_session = SparkSession.builder.getOrCreate()

df_in = spark_session.createDataFrame(
    [
      (1, 'a', 'b', 'c1', 'd'),
      (0, 'a', 'b', 'c2', 'd'),
      (0, 'e', 'f', 'g', 'h'),
      (0, '1', '2', '3', '4'),
      (1, 'x', 'y', 'z1', 'k'),
      (1, 'x', 'y', 'z2', 'k'),
      (1, 'x', 'y', 'z3', 'k'),
      (0, 'x', 'y', 'z4', 'k'),
      (1, '6', '7', '81', '9'),
      (0, '6', '7', '82', '9'),
    ],
    ['c1', 'c2', 'c3', 'c4', 'c5']
)

df_out = spark_session.createDataFrame(
    [
      ('a', 'b', 'c1-c2', 'd'),
      ('e', 'f', 'g', 'h'),
      ('1', '2', '3', '4'),
      ('x', 'y', 'z1-z2-z3-z4', 'k'), 
      ('6', '7', '81-82', '9')
    ],
    ['c2', 'c3', 'c4', 'c5']
)

df_in.show()
df_out.show()
我怎样才能解决这个问题。多谢各位


已更新 输入

输出

预期产出


x | y | select-from-a | k

此解决方案即使在数据集位于多个分区且未排序的情况下也有效

从pyspark.sql.window导入窗口
从pyspark.sql导入函数为F
orderByColumns=[F.col('c4')、F.col('c1').cast('int').desc()]
partitionColumns=[F.col(column)表示['c2'、'c3'、'c5']中的列]
orderBy中的df_(orderByColumns)\
.withColumn('ranked',F.dense_rank().over(Window.partitionBy(partitionColumns).orderBy(orderByColumns)))\
.withColumn('c4-ranged')、F.concat(F.col('ranged')、F.lit('=')、F.col('c4'))\
.groupBy(分区列)\
.agg(F.collect_list('c4排名')。别名('c4'))\
.选择(
F.col(‘c2’),
F.col('c3'),
F.regexp_replace(F.array_join(F.col('c4'),“-”,“\d+=”,“”)。别名('c4'),
F.col('c5')
)\
.show()

安装程序
df_in=sparkSession.createDataFrame(
[
(1),‘a’、‘b’、‘c1’、‘d’,
(0,'a','b','c2','d'),
(0,'e','f','g','h'),
(0, '1', '2', '3', '4'),
(1,'x','y','z1','k'),
(1,'x','y','z2','k'),
(1,'x','y','z3','k'),
(0,'x','y','z4','k'),
(1, '6', '7', '81', '9'),
(0, '6', '7', '82', '9'),
],
['c1','c2','c3','c4','c5']
).重新分配(5)
df_in.show()
在我跑步时提供(每次跑步可能都会提供)


我不太明白
c1列的效果。例如,如果x-y-行包含
0
而不是
c1
中的
1
s,则预期输出会发生怎样的变化?@werner c1始终是1或0,c1是一个标志,让您知道c4列的当前行已完全或被剪切到下一行(因为c4列的长度超过了限制),例如:c4是nvarchar2(4000),如果c4的内容=40001,则最后一个字母将存储在下一行中,因此最后一次使用0而不是1的中断?@anky yesright@anky或者在开始时,它不需要中断,c1也=0我想知道,真的需要df_in.orderBy(orderByColumns)首先,我不知道这是什么意思某些情况下不通过,您的解决方案是一般的,但它不保持序列条件,例如,我更新了这个问题,请回顾一下上面我删除了列表顺序中的c4,这是可行的,但我必须保持原始数据中c4的顺序
df_in = spark_session.createDataFrame(
    [
      ('0', 1, 'a', 'b', 'c1', 'd'),
      ('0', 0, 'a', 'b', 'c2', 'd'),
      ('0', 0, 'e', 'f', 'g', 'h'),
      ('0', 0, '1', '2', '3', '4'),
      ('0', 1, 'x', 'y', 'sele', 'k'),
      ('0', 1, 'x', 'y', 'ct ', 'k'),
      ('0', 1, 'x', 'y', 'from', 'k'),
      ('0', 0, 'x', 'y', 'a', 'k'),
      ('0', 1, '6', '7', '81', '9'),
      ('0', 0, '6', '7', '82', '9'),
    ],
    ['c0', 'c1', 'c2', 'c3', 'c4', 'c5']
)
+---+---+-----------+---+
| c2| c3|         c4| c5|
+---+---+-----------+---+
|  1|  2|          3|  4|
|  x|  y|z1-z2-z3-z4|  k|
|  e|  f|          g|  h|
|  6|  7|      81-82|  9|
|  a|  b|      c1-c2|  d|
+---+---+-----------+---+
+---+---+---+---+---+
| c1| c2| c3| c4| c5|
+---+---+---+---+---+
|  1|  x|  y| z2|  k|
|  0|  x|  y| z4|  k|
|  1|  a|  b| c1|  d|
|  0|  1|  2|  3|  4|
|  0|  6|  7| 82|  9|
|  0|  a|  b| c2|  d|
|  0|  e|  f|  g|  h|
|  1|  6|  7| 81|  9|
|  1|  x|  y| z3|  k|
|  1|  x|  y| z1|  k|
+---+---+---+---+---+