Apache spark 基于另一列更新pyspark数据帧列

Apache spark 基于另一列更新pyspark数据帧列,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,下面是pyspark中的数据帧。我想根据tests列中的值更新data frame中的列val df.show() +---------+----+---+ | tests| val|asd| +---------+----+---+ | test1| Y| 1| | test2| N| 2| | test2| Y| 1| | test1| N| 2| | test1| N| 3| | test3| N| 4| |

下面是
pyspark
中的数据帧。我想根据
tests
列中的值更新
data frame
中的列
val

df.show()
+---------+----+---+
|    tests| val|asd|
+---------+----+---+
|    test1|   Y|  1|
|    test2|   N|  2|
|    test2|   Y|  1|
|    test1|   N|  2|
|    test1|   N|  3|
|    test3|   N|  4|
|    test4|   Y|  5|
+---------+----+---+
我想在任何给定的
测试
具有
val
Y
时更新该值,然后该特定测试的所有
val
都应更新为
Y
。如果没有,他们有什么价值观

基本上,我希望
数据帧
如下所示

result_df.show()

+---------+----+---+
|    tests| val|asd|
+---------+----+---+
|    test1|   Y|  1|
|    test2|   Y|  2|
|    test2|   Y|  1|
|    test1|   Y|  2|
|    test1|   Y|  3|
|    test3|   N|  4|
|    test4|   Y|  5|
+---------+----+---+
我应该怎么做才能做到这一点。

这里有一个解决方案。 首先,我们找出每个测试是否有值Y

导入pyspark.sql.sf函数
by_test=df.groupBy('tests').agg(sf.sum((sf.col('val')='Y')).cast('int')).alias('HasY'))
by_test.show()
+-----+----+
|测试|草率|
+-----+----+
|测试4 | 1|
|测试3 | 0|
|测试1 | 1|
|测试2 | 1|
+-----+----+
连接回原始数据帧

df=df.join(通过_test,on='tests'))
df.show()
+-----+---+---+----+
|测试| val | asd |仓促|
+-----+---+---+----+
|测试4 | Y | 5 | 1|
|测试3 | N | 4 | 0|
|测试1 | Y | 1 | 1|
|测试1 | N | 2 | 1|
|测试1 | N | 3 | 1|
|测试2 | N | 2 | 1|
|测试2 | Y | 1 | 1|
+-----+---+---+----+
使用when/other创建具有相同名称的新列

df=df.withColumn('val',sf.when(sf.col('HasY')>0,'Y')。否则(sf.col('val'))
df=df.drop('HasY')
df.show()
+-----+---+---+
|测试| val | asd|
+-----+---+---+
|测试4 | Y | 5|
|测试3 | N | 4|
|测试1 | Y | 1|
|测试1 | Y | 2|
|测试1 | Y | 3|
|测试2 | Y | 2|
|测试2 | Y | 1|
+-----+---+---+
这里有一个解决方案。 首先,我们找出每个测试是否有值Y

导入pyspark.sql.sf函数
by_test=df.groupBy('tests').agg(sf.sum((sf.col('val')='Y')).cast('int')).alias('HasY'))
by_test.show()
+-----+----+
|测试|草率|
+-----+----+
|测试4 | 1|
|测试3 | 0|
|测试1 | 1|
|测试2 | 1|
+-----+----+
连接回原始数据帧

df=df.join(通过_test,on='tests'))
df.show()
+-----+---+---+----+
|测试| val | asd |仓促|
+-----+---+---+----+
|测试4 | Y | 5 | 1|
|测试3 | N | 4 | 0|
|测试1 | Y | 1 | 1|
|测试1 | N | 2 | 1|
|测试1 | N | 3 | 1|
|测试2 | N | 2 | 1|
|测试2 | Y | 1 | 1|
+-----+---+---+----+
使用when/other创建具有相同名称的新列

df=df.withColumn('val',sf.when(sf.col('HasY')>0,'Y')。否则(sf.col('val'))
df=df.drop('HasY')
df.show()
+-----+---+---+
|测试| val | asd|
+-----+---+---+
|测试4 | Y | 5|
|测试3 | N | 4|
|测试1 | Y | 1|
|测试1 | Y | 2|
|测试1 | Y | 3|
|测试2 | Y | 2|
|测试2 | Y | 1|
+-----+---+---+

使用
max
窗口功能并
选择expr

df.selectExpr(
“测试”,“最大值(val)超过(按测试划分)为val”,“asd”
).show()
+-----+---+---+
|测试| val | asd|
+-----+---+---+
|测试4 | Y | 5|
|测试3 | N | 4|
|测试1 | Y | 1|
|测试1 | Y | 2|
|测试1 | Y | 3|
|测试2 | Y | 2|
|测试2 | Y | 1|
+-----+---+---+

使用
max
窗口功能并
选择expr

df.selectExpr(
“测试”,“最大值(val)超过(按测试划分)为val”,“asd”
).show()
+-----+---+---+
|测试| val | asd|
+-----+---+---+
|测试4 | Y | 5|
|测试3 | N | 4|
|测试1 | Y | 1|
|测试1 | Y | 2|
|测试1 | Y | 3|
|测试2 | Y | 2|
|测试2 | Y | 1|
+-----+---+---+

我收到以下错误
回溯(最近一次调用):文件“/usr/hdp/current/spark-client/python/pyspark/sql/dataframe.py”,第876行,在selectExpr jdf=self.\u jdf.selectExpr(self.\u jseq(expr)文件“/usr/hdp/current/spark-client/python/pyspark/sql/utils.py”,第45行,装饰返回f(*a,**kw)py4j.protocol.Py4JJavaError:调用o177.selectExpr时出错:java.lang.RuntimeException:[1.15]失败:输入结束时,在scala.sys.package$处预期最大值(val)超过(测试分区)为val^。错误(package.scala:27)
我从
pyspark.sql
导入了
Window
函数,而且我使用的是
spark 1.6
@user9367133,这应该适合您。同样,您可以
导入pyspark.sql.functions作为f
并执行
df.select('tests',f.max('val')。over(Window.partitionBy('tests'))。别名('val'),'asd')。show()
我收到以下错误
回溯(最近一次调用):文件“/usr/hdp/current/spark-client/python/pyspark/sql/dataframe.py”,第876行,在selectExpr jdf=self.\u jdf.selectExpr(self.\u jseq(expr)文件“/usr/hdp/current/spark-client/python/pyspark/sql/utils.py”,第45行,装饰返回f(*a,**kw)py4j.protocol.Py4JJavaError:调用o177.selectExpr时出错:java.lang.RuntimeException:[1.15]失败:输入结束时,在scala.sys.package$处预期最大值(val)超过(测试分区)为val^。错误(package.scala:27)
我从
pyspark.sql
导入了
Window
函数,而且我使用的是
spark 1.6
@user9367133,这应该适合您。同样,您可以
导入pyspark.sql.functions作为f
并执行
df.select('tests',f.max('val')。over(Window.partitionBy('tests'))。别名('val'),'asd')。show()