将 scala 中的伴随对象转换为 Python

Posted

技术标签:

【中文标题】将 scala 中的伴随对象转换为 Python【英文标题】:Translating the companion object in scala to Python 【发布时间】:2018-09-05 16:24:31 【问题描述】:

我已将以下 Spark Scala 代码翻译成 Python 版本。

package wscalalearning00
import org.apache.spark._
import org.apache.spark.SparkContext._
import org.apache.log4j._
import org.apache.spark.util.StatCounter

object wtry001 
 def main(args: Array[String]) 

     Logger.getLogger("org").setLevel(Level.ERROR)
   class BballStatCounter extends Serializable 
          val stats: StatCounter = new StatCounter()
          var missing: Long = 0

          def add(x: Double): BballStatCounter = 
             if (x.isNaN) 
                  missing += 1
                 else 

                stats.merge(x)
                
                this
              

  
 object BballStatCounter extends Serializable 
  def apply(x: Double) = new BballStatCounter().add(x)


     // Create a SparkContext using every core of the local machine
    val sc = new SparkContext(new SparkConf().setAppName("Spark Word Count").setMaster("local")) 
    val testData = (1 to 10000).toArray.map(x=>x.toDouble)
    val stats1 = sc.parallelize(testData)
    val stat3 = stats1.map(b=>BballStatCounter(b))
    stat3.foreach(println)        

 

Python 版本:

 import math
    import findspark
    findspark.init()
    from pyspark.sql import SparkSession
    from pyspark.statcounter import StatCounter
    class BballStatCounter(object):

        stats = StatCounter()
        missing=0

        @staticmethod
        def add(x):
            print("add")
            if math.isnan(x):
                BballStatCounter.missing += x
            else:
               BballStatCounter.stats.merge(x)
            return BballStatCounter.stats

    conf = SparkConf().setAppName("SparkExampleRDD").setMaster("local")
    sc = SparkContext(conf=conf)
    testData =map(lambda x: float(x),range(0,10000))
    stats1 = sc.parallelize(testData)
    print(stats1)
    stat3 = stats1.map(lambda b: BballStatCounter.add(b))
    stat3.foreach(print)

在执行上述 Python 代码时,它会打印 (count: 22, mean: 10.5, stdev: 6.34428877022, max: 21.0, min: 0.0),而 Scala 代码会打印类似 BballStatCounter$2@7a811dd5 的内容。我认为 Scala 代码正在返回同一类的实例。如果我的一般方法和/或语法错误,请告诉我。谢谢。

【问题讨论】:

跳出来的一件事是BballStatCounter.missing = +other.missing应该可能BballStatCounter.missing += other.missing 是/应该合并是一个静态方法 - 如果不是,它应该首先有一个 self 参数。如果您发布了一个适当的最小完整可验证示例,包括显示您获得的结果所需的所有内容,则可能可以运行您的代码并对其进行调试,但您还没有这样做,您必须自己做。生命太短暂,无法进行太多奇怪代码的思想实验。见***.com/help/mcve @barny。根据您的输入,我添加了最少的可验证代码。 【参考方案1】:

试试这个

class BballStatCounter:

   def __init__(self):
      self.stats = StatCounter()
      self.missing = 0

    @staticmethod
    def add(x):
        stats = StatCounter()
        missing = 0
        if math.isnan(x):
            BballStatCounter.missing += x
        else:
            BballStatCounter.stats.merge(x,stats,missing)


    def merge(other,stats,missing):
       # stats = BballStatCounter.StatCounter()
        #other = BballStatCounter()
        BballStatCounter.stats.merge(other.stats)
        BballStatCounter.missing = +other.missing
        return self

然后做

stat3 = stats1.map(lambda b: BballStatCounter.add(b))
stat3.foreach(print)

我可能不会给你正确的代码,因为我对函数的作用知之甚少。只关注我如何在函数之间传递变量。- 希望你能找到答案。

【讨论】:

StatCounter 有一个名为merge().add() 的预定义方法从StatCounter 调用merge()。此外,如果方法 add() 返回类似于 this 的内容。 更新了最小工作代码。在类中创建stats 和在静态方法中创建stats 有什么区别?我是 Python 编程的新手,尝试探索这种语言。所以这个问题就跳出来了?

以上是关于将 scala 中的伴随对象转换为 Python的主要内容,如果未能解决你的问题,请参考以下文章

AWS EMR 中的数据转换,无需使用 Scala 或 Python

将数据转换为 spark scala 中的类对象列表

通过给定的泛型类型 Scala 获取类的伴随对象

在Scala中使用抽象类和工厂时相互调用方法(伴随对象)

Scala快速入门--正则对象

Scala案例类伴随对象 - 类型名称冲突