对于Spark数据框,我想基于具有相同ID的其他行来更新行值。
例如, 我在下面有记录,
id,value
1,10
1,null
1,null
2,20
2,null
2,null
我想得到如下结果
id,value
1,10
1,10
1,10
2,20
2,20
2,20
总结一下,值列在某些行中为空,如果还有另一行具有相同ID且具有有效值的行,我想对其进行更新。
在sql中,我可以使用inner-join编写一个更新语句,但是在Spark-sql中找不到相同的方法。
更新CombineCols a 内部联接CombineCols b 在a.id = b.id上 设置a.value = b.value (这是我在sql中的操作方式)
答案 0 :(得分:1)
让我们使用SQL方法解决此问题-
@Bean
public ServletWebServerFactory servletContainer() {
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
@Override
protected void postProcessContext(Context context) {
SecurityConstraint securityConstraint = new SecurityConstraint();
securityConstraint.setUserConstraint("CONFIDENTIAL");
SecurityCollection collection = new SecurityCollection();
collection.addPattern("/*");
securityConstraint.addCollection(collection);
context.addConstraint(securityConstraint);
}
};
tomcat.addAdditionalTomcatConnectors(redirectConnector());
return tomcat;
}
private Connector redirectConnector() {
Connector connector = new Connector(
TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
connector.setScheme("http");
connector.setPort(8080);
connector.setSecure(false);
connector.setRedirectPort(8443);
return connector;
}
注意事项:该代码假定任何特定myValues = [(1,10),(1,None),(1,None),(2,20),(2,None),(2,None)]
df = sqlContext.createDataFrame(myValues,['id','value'])
df.registerTempTable('table_view')
df1=sqlContext.sql(
'select id, sum(value) over (partition by id) as value from table_view'
)
df1.show()
+---+-----+
| id|value|
+---+-----+
| 1| 10|
| 1| 10|
| 1| 10|
| 2| 20|
| 2| 20|
| 2| 20|
+---+-----+
的值只有一个non-null
。当我们使用id
值时,我们必须使用groupby
函数,而我已经使用了aggregation
。如果任何sum
都有2个non-null
值,则将对进行汇总。如果id
可以有多个id
值,那么最好使用non-null
,以便我们获得其中一个值而不是min/max
。
sum
答案 1 :(得分:0)
您可以使用window来执行此操作(在pyspark中):
from pyspark.sql import functions as F
from pyspark.sql.window import Window
# create dataframe
df = sc.parallelize([
[1,10],
[1,None],
[1,None],
[2,20],
[2,None],
[2,None],
]).toDF(('id', 'value'))
window = Window.partitionBy('id').orderBy(F.desc('value'))
df \
.withColumn('value', F.first('value').over(window)) \
.show()
结果:
+---+-----+
| id|value|
+---+-----+
| 1| 10|
| 1| 10|
| 1| 10|
| 2| 20|
| 2| 20|
| 2| 20|
+---+-----+
您可以在scala中使用相同的功能。