我有一个包含各种列的DataFrame。
一列包含Map [Integer,Integer []]。
它看起来像{ 2345 -> [1,34,2]; 543 -> [12,3,2,5]; 2 -> [3,4]}
现在我需要做的是过滤掉一些键。
我在Java中有一组整数(javaIntSet),我应该使用它来过滤
col(x).keySet.isin(javaIntSet)
即。上面的地图应该只包含密钥2和543而不包含其他两个,并且在过滤后应该看起来像{543 -> [12,3,2,5]; 2 -> [3,4]}
。
如何使用Java Column Class的文档很稀疏。
如何提取col(x),以便我可以在java中过滤它,然后用过滤后的地图替换单元格数据。或者我正在忽略列的任何有用功能。
我可以写一个UDF2<Map<Integer, Integer[]>,Set<Integer>,Map<Integer,Integer[]>
我可以写一个UDF1<String,String>
但我不太确定它如何适用于更复杂的参数。
通常,javaIntSet只有十几个,通常少于100个值。地图通常也只有少数条目(通常为0-5)。
我必须在Java中这样做(不幸的是),但我熟悉Scala。我将自己翻译成Java的Scala答案已经非常有用了。
答案 0 :(得分:2)
您不需要UDF。可以用一个更干净,但你可以用Article
:
CategoryId
然后你可以使用explode:
var express = require('express');
var ws = require('nodejs-websocket');
var app = express();
var socket = ws.connect("ws://localhost:5000");
var port = 8000;
app.get('/', function(req, res) {
var r = JSON.stringify({
type: "page request",
request: {
url: req.query.url,
app: req.query.app
}
});
socket.on("text", function(str){
console.log(str);
var d = JSON.parse(str);
res.send(d.response.body);
return;
});
socket.sendText(r);
});
app.listen(port, function(){
console.log("Node app is running on port", port);
});
如果您确实想要DataFrame.explode
,它将如下所示:
case class MapTest(id: Int, map: Map[Int,Int])
val mapDf = Seq(
MapTest(1, Map((1,3),(2,10),(3,2)) ),
MapTest(2, Map((1,12),(2,333),(3,543)) )
).toDF("id", "map")
mapDf.show
+---+--------------------+
| id| map|
+---+--------------------+
| 1|Map(1 -> 3, 2 -> ...|
| 2|Map(1 -> 12, 2 ->...|
+---+--------------------+
mapDf.explode($"map"){
case Row(map: Map[Int,Int] @unchecked) => {
val newMap = map.filter(m => m._1 != 1) // <-- do filtering here
Seq(Tuple1(newMap))
}
}.show
+---+--------------------+--------------------+
| id| map| _1|
+---+--------------------+--------------------+
| 1|Map(1 -> 3, 2 -> ...|Map(2 -> 10, 3 -> 2)|
| 2|Map(1 -> 12, 2 ->...|Map(2 -> 333, 3 -...|
+---+--------------------+--------------------+
稍微复杂一点,但最终更灵活。例如,您可以将原始行划分为两行 - 一行包含已过滤掉元素的地图,另一行包含反向的地图 - 已过滤的元素。