Python Pyspark基于对应列中匹配特定条件的最多多列创建列

Python Pyspark基于对应列中匹配特定条件的最多多列创建列,python,apache-spark,pyspark,Python,Apache Spark,Pyspark,假设我有一个Pyspark数据框,id为,3列表示代码桶 col_buckets ["code_1", "code_2", "code_3"] amt_buckets = ["code_1_amt", "code_2_amt", "code_3_amt" ] 和3列,表示对应代码段的金额 col_buckets ["code_1", "code_2", "code_3"] amt_buckets = ["code_1_amt", "code_2_amt", "code_3_amt" ]

假设我有一个Pyspark数据框,id为,3列表示代码桶

col_buckets ["code_1", "code_2", "code_3"]
amt_buckets = ["code_1_amt", "code_2_amt", "code_3_amt" ] 
和3列,表示对应代码段的金额

col_buckets ["code_1", "code_2", "code_3"]
amt_buckets = ["code_1_amt", "code_2_amt", "code_3_amt" ] 
这是一个伪代码,我正在尝试做什么

for el in ['01', '06', '07']
    df= df.withColumn("max_amt_{el}", max(df.select(max(**amt_buckets**) for corresponding col_indices of amt_buckets if ***any of col_buckets*** ==el)))
我将如何做到这一点

以下是一个数据帧示例:


我正在尝试为
spark2.4+
获取max_01、max_07和max_06列,您可以试试这个

df.show() #sample dataframe
#+----------+------+------+------+-----+-----+-----+
#|Primary_id|Code_1|Code_2|Code_3|Amt_1|Amt_2|Amt_3|
#+----------+------+------+------+-----+-----+-----+
#|  Xxxxx998|  null|    01|    04| 2000| 1000|  100|
#|  Xxxxx997|    01|    01|    07|  200|  300|  400|
#|  Xxxxx996|    07|  null|  null|  100| null| null|
#|   Xxxx910|  null|  null|  null|  300|  100|  200|
#+----------+------+------+------+-----+-----+-----+

from pyspark.sql import functions as F

dictionary = dict(zip(['Code_1','Code_2','Code_3'], ['Amt_1','Amt_2','Amt_3']))

df.withColumn("trial", F.array(*[F.array(F.col(x),F.col(y).cast("string"))\
                                          for x,y in dictionary.items()]))\
  .withColumn("Max_01",F.when(F.size(F.expr("""filter(trial,x-> exists(x,y->y='01'))"""))!=0,\
       F.expr("""array_max(transform(filter(trial, x-> exists(x,y-> y='01')),z-> float(z[1])))"""))\
             .otherwise(F.lit(0)))\
  .withColumn("Max_06",F.when(F.size(F.expr("""filter(trial,x-> exists(x,y->y='06'))"""))!=0,\
       F.expr("""array_max(transform(filter(trial, x-> exists(x,y-> y='06')),z-> float(z[1])))"""))\
             .otherwise(F.lit(0)))\
  .withColumn("Max_07",F.when(F.size(F.expr("""filter(trial,x-> exists(x,y->y='07'))"""))!=0,\
       F.expr("""array_max(transform(filter(trial, x-> exists(x,y-> y='07')),z-> float(z[1])))"""))\
             .otherwise(F.lit(0)))\
  .drop("trial").show(truncate=False)

#+----------+------+------+------+-----+-----+-----+------+------+------+
#|Primary_id|Code_1|Code_2|Code_3|Amt_1|Amt_2|Amt_3|Max_01|Max_07|Max_06|
#+----------+------+------+------+-----+-----+-----+------+------+------+
#|Xxxxx998  |null  |01    |04    |2000 |1000 |100  |1000  |0     |0     |
#|Xxxxx997  |01    |01    |07    |200  |300  |400  |300   |400   |0     |
#|Xxxxx996  |07    |null  |null  |100  |null |null |0     |100   |0     |
#|Xxxx910   |null  |null  |null  |300  |100  |200  |0     |0     |0     |
#+----------+------+------+------+-----+-----+-----+------+------+------+

你从哪里得到01,06,07的列表,这是一个已经定义的标准变量吗?是的,这些是我们在dataframe中可能的代码列表中寻找的预定义代码好的,你也可以用dataframe的可视文本替换图像,以便可以复制它。谢谢。我更新了问题,将其包括在内it@MohammadMurtazaHashmi. 您好,谢谢您的帮助,是的,07列应该是100,而不是01Nice,我在想,如果可以使用另一个邮政编码和金额列的文字数组列的数组zip进行过滤,这是否可行。但现在无法测试:)@anky我也在考虑一种方法,使用结构使此动态化,这样我们就不必三次处理列(假设提供了要添加的列列表),只需在末尾选择
col.*
。b会不会更详细更干净。。等我回来再试试can@algorythmsofc,所以我们首先创建一列列表,其中第二维度是[Code_1,Amt_1]等等,然后我们使用高阶函数过滤器遍历列表,过滤掉任何与01(或7或6)不匹配的[[],然后我将其展平以得到[01200,01300],从中过滤出01以得到[200,300]然后用array_max取最大值。第二个过滤器可能不需要,但我不知道是否存在07或某个值可能大于该值的情况,所以我不想冒险。我知道了,这是字符串和array_max的一个小问题,我将在这里更新,并发布其他问题。检查我更新的解决方案,使用transform确保将字符串转换为数字