我已经学会了foldLeft和之间的基本区别reduceLeft
foldLeft:
reduceLeft:
还有其他区别吗?
有两种方法具有相似功能的任何特定原因?
什么时候应该使用reduceLeft,reduceRight,foldLeft,foldRight,scanLeft或scanRight?
我想要一个直觉/概述他们的差异 - 可能有一些简单的例子.
我正在阅读Kotlin的基础知识,我对Kotlin中的函数fold()和reduce()非常困惑,有人能给我一个区分两者的具体例子吗?
我试图了解fold和foldLeft以及各自的reduce和reduceLeft是如何工作的.我用fold和foldLeft作为例子
scala> val r = List((ArrayBuffer(1, 2, 3, 4),10))
scala> r.foldLeft(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1)
scala> res28: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(5)
scala> r.fold(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1)
<console>:11: error: value _1 is not a member of Serializable with Equals
r.fold(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1)
Run Code Online (Sandbox Code Playgroud)
为什么fold不工作foldLeft?什么是Serializable with Equals?我理解fold和foldLeft在参数泛型类型方面有轻微不同的API签名.请指教.谢谢.
reduce与fold技术实施之间的区别是什么?
我知道它们的签名不同,因为它们fold接受附加的参数(即初始值),该参数被添加到每个分区输出中。
fold?提前致谢。
假设我有一个包含(Int,Int)元组的RDD.我希望把它变成一个Vector,其中元组中的第一个Int是索引,第二个是值.
任何想法我该怎么做?
我更新了我的问题并添加了我的解决方案以澄清:我的RDD已经被密钥减少了,并且密钥的数量是已知的.我想要一个向量来更新单个累加器而不是多个累加器.
我的最终解决方案是:
reducedStream.foreachRDD(rdd => rdd.collect({case (x: Int,y: Int) => {
val v = Array(0,0,0,0)
v(x) = y
accumulator += new Vector(v)
}}))
Run Code Online (Sandbox Code Playgroud)
Vector在文档中使用累加器示例.
所以我遇到了一个问题,我在RDD上使用的过滤器可能会创建一个空的RDD.我觉得为了测试空虚而做一个count()会非常昂贵,并且想知道是否有更高效的方法来处理这种情况.
以下是此问题的示例:
val b:RDD[String] = sc.parallelize(Seq("a","ab","abc"))
println(b.filter(a => !a.contains("a")).reduce(_+_))
Run Code Online (Sandbox Code Playgroud)
会给出结果
empty collection
java.lang.UnsupportedOperationException: empty collection
at org.apache.spark.rdd.RDD$$anonfun$reduce$1$$anonfun$apply$36.apply(RDD.scala:1005)
at org.apache.spark.rdd.RDD$$anonfun$reduce$1$$anonfun$apply$36.apply(RDD.scala:1005)
at scala.Option.getOrElse(Option.scala:120)
at org.apache.spark.rdd.RDD$$anonfun$reduce$1.apply(RDD.scala:1005)
at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:147)
at org.apache.spark.rdd.RDDOperationScope$.withScope(RDDOperationScope.scala:108)
at org.apache.spark.rdd.RDD.withScope(RDD.scala:306)
at org.apache.spark.rdd.RDD.reduce(RDD.scala:985)
Run Code Online (Sandbox Code Playgroud)
有没有人对如何解决这个边缘案件有任何建议?
据我所知aggregate,fold这是一种概括,反过来又是一种概括reduce.
类似地combineByKey,aggregateByKey这是一种概括,其反过来又是概括,foldByKey而反过来又是概括reduceByKey.
但是,我很难找到这七种方法中的每种方法的简单例子,而这些方法又可以仅由它们表达,而不是它们不那么通用的版本.例如,我找到了http://blog.madhukaraphatak.com/spark-rdd-fold/给出一个例子fold,但我也能够reduce在相同的情况下使用.
到目前为止我发现了什么:
fold只要是关联的,而一个reduce必须是可交换另外:/sf/answers/1761115331/(不过,我还是不知道有什么好的简单例如.)在/sf/answers/1864514991/中,我读到折叠需要两个属性才能保持...fold结束reduce),如"添加所有元素并添加3"并使用3作为零值,但这会产生误导,因为每个分区都会添加3个,而不仅仅是一旦.此外,fold根据我的理解,这根本不是目的- 它不是一个特征,而是实现它以便能够采用非交换函数的必要性.这七种方法的简单例子是什么?
我一直在读一个很好的答案,以减少和foldLeft /折叠功能编程(尤其是Scala和斯卡拉API)的区别?由samthebest提供,我不确定我是否理解所有细节:
根据答案(reducevs foldLeft):
一个很大的区别(...)是减少应该给予一个可交换的幺半群,(...)
这种区别对于大数据/ MPP /分布式计算非常重要,并且存在减少甚至存在的全部原因.
和
Reduce正式定义为MapReduce范例的一部分,
我不确定这两个陈述是如何结合的.任何人都可以对此有所了解吗?
我测试了不同的系列,我没有看到reduce和之间的性能差异foldLeft.它看起来像是ParSeq一个特例,是吗?
我们真的需要订单来定义fold吗?
我们无法定义折叠,因为块没有排序,折叠只需要关联性,而不是交换性.
为什么它不能被推广到无序集合?
我需要得到一个2d列表的总大小.这是我的实施:
fun totalSize(parts: List<List<String>>): Int {
return parts.reduce { total, next -> total + next.size }
}
Run Code Online (Sandbox Code Playgroud)
我得到类型推断失败.必需的Int,Got List.但是next.size应该返回Int.
由于Monoid是关闭的(a - > a - > a),我们怎样才能获得第二种类型'b'?我的印象是折叠太过宽松,在某种意义上我可以使用折叠功能而不是关闭.您还会注意到fold和foldMap只有'a'.
下面是可折叠类型类的片段:
class Foldable t where
fold :: Monoid m => t m -> m
foldMap :: Monoid m => (a -> m) -> t a -> m
foldr :: (a -> b -> b) -> b -> t a -> b
Run Code Online (Sandbox Code Playgroud)
例如:
foldr (+) 0 [1..5] // ok (+) is a monoid
foldr (++) "" ["ab", " cd"] // ok (++) is a monoid for String
foldr (:) [] [1,2,3] // (:) :: …Run Code Online (Sandbox Code Playgroud)