我目前正在阅读《从业者图形数据指南》,并试图解决以下问题(仅用于学习目的)。以下是books movie数据集的上下文,在本例中,该数据集使用“标记”顶点、“movie”顶点和“额定”边,其额定属性为1-5。
为了练习,并扩展我对书中概念的理解,我想让所有电影都标记为“喜剧”,并计算平均NP。为此,我想将所有正(1)和中性或负(-1)评级汇总到一个列表中。然后我想把这些值的总和除以这个列表中变量的数量(平均值)。这就是我所尝试的:
dev.withSack{[]}{it.clone()}. // create a sack with an empty list that clones when split
V().has('Tag', 'tag_name', 'comedy').
in('topic_tagged').as('film'). // walk to movies tagged as comedy
inE('rated'). // walk to the rated edges
choose(values('rating').is(gte(3.0)),
sack(addAll).by(constant([1.0])),
sack(addAll).by(constant([-1.0]))). // add a value or 1 or -1 to this movies list, depending on the rating
group().
by(select('film').values('movie_title')).
by(project('a', 'b').
by(sack().unfold().sum()). // add all values from the list
by(sack().unfold().count()). // Count the values in the list
math('a / b')).
order(local).
by(values, desc)
这最终导致每部电影要么是“1.0”,要么是“-1.0”。
"Journey of August King The (1995)": "1.0",
"Once Upon a Time... When We Were Colored (1995)": "1.0", ...
在我的测试中,这些值似乎没有像我预期的那样聚合到集合中。我尝试了各种方法,但都没有达到我的预期结果。
我知道我可以通过对初始值为“0.0”的sack进行加减,然后除以边缘计数来实现这个结果,但我希望通过使用列表并避免对边缘进行额外遍历来获得计数,从而获得更有效的解决方案。
使用列表可以实现我的结果吗?如果是,如何?
编辑1:
下面的代码简单得多,取自Kelvins示例,只需使用折叠步骤即可聚合每个评级:
dev.V().
has('Tag', 'tag_name', 'comedy').
in('topic_tagged').
project('movie', 'result').
by('movie_title').
by(inE('rated').
choose(values('rating').is(gte(3.0)),
constant(1.0),
constant(-1.0)).
fold()) // replace fold() with mean() to calculate the mean, or do something with the collection
我觉得有点尴尬,我完全忘记了折叠步骤,因为折叠和展开是如此常见。我想是想得太多了。
您可以考虑使用聚合而不是sack的不同方法。您还可以使用均值步骤来避免需要数学步骤。由于我没有你的数据,我举了一个例子,在你的案例中使用了航空路线数据集,并使用机场标高而不是电影评分。
gremlin> g.V().hasLabel('airport').limit(10).values('elev')
==>1026
==>151
==>542
==>599
==>19
==>143
==>14
==>607
==>64
==>313
使用和你类似的加权系统
gremlin> g.V().hasLabel('airport').limit(10).
......1> choose(values('elev').is(gt(500)),
......2> constant(1),
......3> constant(-1))
==>1
==>-1
==>1
==>1
==>-1
==>-1
==>-1
==>1
==>-1
==>-1
这些结果可以聚合成一个大容量集
gremlin> g.V().hasLabel('airport').limit(10).
......1> choose(values('elev').is(gt(500)),
......2> constant(1),
......3> constant(-1)).
......4> aggregate('x').
......5> cap('x')
==>[1,1,1,1,-1,-1,-1,-1,-1,-1]
从那里我们可以得到平均值
gremlin> g.V().hasLabel('airport').limit(10).
......1> choose(values('elev').is(gt(500)),
......2> constant(1),
......3> constant(-1)).
......4> aggregate('x').
......5> cap('x').
......6> unfold().
......7> mean()
==>-0.2
现在,这当然是人为的,因为您通常不会执行聚合('x'). cap('x'). unfol(). means()
,您只需使用means()
本身。但是使用这种模式,您应该能够解决您的问题。
编辑以添加
仔细考虑一下,您可能甚至不需要聚合
就可以编写查询-类似于这样(下图)。我使用空中路线距离边缘属性来模拟类似于您的查询的东西。该示例只是使用一个机场来保持简单。首先只是创建分数列表...
gremlin> g.V().has('airport','code','SAF').
......1> project('airport','mean').
......2> by('code').
......3> by(outE().
......4> choose(values('dist').is(gt(350)),
......5> constant(1),
......6> constant(-1)).
......7> fold())
==>[airport:SAF,mean:[1,1,1,-1]]
最后创造平均值
gremlin> g.V().has('airport','code','SAF').
......1> project('airport','mean').
......2> by('code').
......3> by(outE().
......4> choose(values('dist').is(gt(350)),
......5> constant(1),
......6> constant(-1)).
......7> mean())
==>[airport:SAF,mean:0.5]
再次编辑
如果edge属性可能不存在,您可以这样做...
gremlin> g.V().has('airport','code','SAF').
......1> project('airport','mean').
......2> by('code').
......3> by(outE().
......4> coalesce(values('x'),constant(100)).
......5> choose(identity().is(gt(350)),
......6> constant(1),
......7> constant(-1)).
......8> fold())
==>[airport:SAF,mean:[-1,-1,-1,-1]]
Map 集合的遍历与 List 和 Set 集合不同。Map 有两组值,因此遍历时可以只遍历值的集合,也可以只遍历键的集合,也可以同时遍历。Map 以及实现 Map 的接口类(如 HashMap、TreeMap、LinkedHashMap、Hashtable 等)都可以用以下几种方式遍历。 1)在 for 循环中使用 entries 实现 Map 的遍历(最常见和最常用的)。 2)使用 for-e
《 Java Iterator遍历Collection集合元素》一节中主要讲解如何使用 Iterator 接口迭代访问 Collection 集合里的元素,除了这个方法之外,我们还可以使用 Java 5 提供的 foreach 循环迭代访问集合元素,而且更加便捷。如下程序示范了使用 foreach 循环来迭代访问集合元素。 输出结果为: 小牛知识库C++教程 小牛知识库C语言教程 小牛知识库Jav
集合的遍历 在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口Iterator。Iterator接口也是Java集合中的一员,但它与Collection、Map接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。 Iterator迭代器对
Java 8 为 Iterable 接口新增了一个 forEach(Consumer action) 默认方法,该方法所需参数的类型是一个函数式接口,而 Iterable 接口是 Collection 接口的父接口,因此 Collection 集合也可直接调用该方法。 当程序调用 Iterable 的 forEach(Consumer action) 遍历集合元素时,程序会依次将集合元素传给 Co
运行此代码时: 引发异常: 系统。无效操作异常:集合被修改;枚举操作可能无法执行。 怎么做。NET知道该集合在枚举器迭代该集合时被修改了吗?集合对象中是否有此标志?
问题内容: 说我有一个数组。如何一次迭代两个? 问题答案: 您可以使用称为stride(to :, by :)的进度循环,每n个元素对元素进行一次迭代: Xcode 8.3.2•Swift 3.1