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()