Scala:计算标准差的通用方法是什么

2024-04-09

我很好奇如何编写一个通用方法来计算 scala 中的标准差和方差。我有一个计算平均值的通用方法(从这里窃取:在 Scala 中编写通用均值函数 https://stackoverflow.com/questions/6188990/writing-a-generic-mean-function-in-scala)

我试图转换平均值计算以获得标准差和方差,但对我来说它看起来是错误的。目前,泛型远远超出了我的 Scala 编程技能。

计算平均值、标准差和方差的代码是这样的:

package ca.mikelavender

import scala.math.{Fractional, Integral, Numeric, _}

package object genericstats {

  def stdDev[T: Numeric](xs: Iterable[T]): Double = sqrt(variance(xs))

  def variance[T: Numeric](xs: Iterable[T]): Double = implicitly[Numeric[T]] match {
    case num: Fractional[_] => {
      val avg = mean(xs)
      num.toDouble(
        xs.foldLeft(num.zero)((b, a) =>
          num.plus(b, num.times(num.minus(a, avg), num.minus(a, avg))))) /
        xs.size
    }
    case num: Integral[_] => {
      val avg = mean(xs)
      num.toDouble(
        xs.foldLeft(num.zero)((b, a) =>
          num.plus(b, num.times(num.minus(a, avg), num.minus(a, avg))))) /
        xs.size
    }
  }

  /**
    * https://stackoverflow.com/questions/6188990/writing-a-generic-mean-function-in-scala
    */
  def mean[T: Numeric](xs: Iterable[T]): T = implicitly[Numeric[T]] match {
    case num: Fractional[_] => import num._; xs.sum / fromInt(xs.size)
    case num: Integral[_] => import num._; xs.sum / fromInt(xs.size)
    case _ => sys.error("Undivisable numeric!")
  }

}

我觉得方差方法中的匹配案例是不需要的或者可以更优雅。也就是说,代码的口是心非对我来说似乎非常错误,我应该能够仅使用匹配来获取数字类型,然后将其传递给执行计算的单个代码块。

我不喜欢的另一件事是它总是返回一个Double。我觉得它应该返回相同的输入数字类型,至少对于小数值而言。

那么,对于如何改进代码并使其更漂亮有什么建议吗?


像这样的类型类的目标Numeric是为类型提供一组操作,以便您可以编写对具有该类型类实例的任何类型通用的代码。Numeric提供一组操作及其子类Integral and Fractional另外还提​​供了更具体的(但它们也描述了更少的类型)。如果您不需要这些更具体的操作,您可以简单地在以下级别工作Numeric,但不幸的是在这种情况下你这样做了。

让我们从mean。这里的问题是,除法对于整数和分数类型意味着不同的东西,并且根本不为仅提供除法的类型提供除法。Numeric. The 您已链接的答案 https://stackoverflow.com/a/6190665/334519来自 Daniel 的通过调度运行时类型来解决这个问题Numeric实例,如果实例不是一个,则崩溃(在运行时)Fractional or Integral.

我不同意丹尼尔(或者至少五年前的丹尼尔)的观点,并说这并不是一个很好的方法——它既掩盖了真正的差异,又同时抛弃了很多类型安全。我认为存在三个更好的解决方案。

只为小数类型提供这些操作

您可能会认为取平均值对于整数类型没有意义,因为积分除法会丢失结果的小数部分,并且只为分数类型提供它:

def mean[T: Fractional](xs: Iterable[T]): T = {
  val T = implicitly[Fractional[T]]

  T.div(xs.sum, T.fromInt(xs.size))
}

或者使用漂亮的隐式语法:

def mean[T: Fractional](xs: Iterable[T]): T = {
  val T = implicitly[Fractional[T]]
  import T._

  xs.sum / T.fromInt(xs.size)
}

最后一点语法要点:如果我发现我必须写implicitly[SomeTypeClass[A]]为了获取对类型类实例的引用,我倾向于对上下文绑定进行脱糖([A: SomeTypeClass]部分)来清理一下:

def mean[T](xs: Iterable[T])(implicit T: Fractional[T]): T =
  T.div(xs.sum, T.fromInt(xs.size))

不过,这完全是一个品味问题。

返回具体的分数类型

你也可以做mean返回具体的分数类型,例如Double,然后简单地转换Numeric在执行操作之前将值设置为该类型:

def mean[T](xs: Iterable[T])(implicit T: Numeric[T]): Double =
  T.toDouble(xs.sum) / xs.size

或者,等效地但与toDouble语法为Numeric:

import Numeric.Implicits._

def mean[T: Numeric](xs: Iterable[T]): Double = xs.sum.toDouble / xs.size

这为整数和小数类型提供了正确的结果(最高精度为Double),但代价是使您的操作不那么通用。

创建一个新类型类

最后,您可以创建一个新的类型类,为以下对象提供共享除法运算:Fractional and Integral:

trait Divisible[T] {
  def div(x: T, y: T): T
}

object Divisible {
  implicit def divisibleFromIntegral[T](implicit T: Integral[T]): Divisible[T] =
    new Divisible[T] {
      def div(x: T, y: T): T = T.quot(x, y)
    }

  implicit def divisibleFromFractional[T](implicit T: Fractional[T]): Divisible[T] =
    new Divisible[T] {
      def div(x: T, y: T): T = T.div(x, y)
    }
}

进而:

def mean[T: Numeric: Divisible](xs: Iterable[T]): T =
  implicitly[Divisible[T]].div(xs.sum, implicitly[Numeric[T]].fromInt(xs.size))

这本质上是原始版本的更有原则性的版本mean- 您不是在运行时分派子类型,而是使用新的类型类来表征子类型。有更多代码,但不可能出现运行时错误(当然除非xs是空的,等等,但这是所有这些方法都会遇到的正交问题)。

结论

在这三种方法中,我可能会选择第二种,对于您的情况来说,这似乎特别合适,因为您的variance and stdDev已经返回Double。在这种情况下,整个事情将如下所示:

import Numeric.Implicits._

def mean[T: Numeric](xs: Iterable[T]): Double = xs.sum.toDouble / xs.size

def variance[T: Numeric](xs: Iterable[T]): Double = {
  val avg = mean(xs)

  xs.map(_.toDouble).map(a => math.pow(a - avg, 2)).sum / xs.size
}

def stdDev[T: Numeric](xs: Iterable[T]): Double = math.sqrt(variance(xs))

……你就完成了。

在真实的代码中我可能会看一个像这样的库Spire https://github.com/non/spire不过,而不是使用标准库的类型类。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Scala:计算标准差的通用方法是什么 的相关文章

  • 协议本身不符合?

    为什么这段 Swift 代码无法编译 protocol P struct S P let arr P S extension Array where Element P func test
  • 继承的静态成员的静态初始化

    考虑这个示例代码 public class A
  • Scala 2.9 无法在 Windows XP 上运行“hello world”示例

    我正在尝试在 Windows XP 上使用 scala 2 9 1 Final 运行 HelloWorld 示例 object HelloWorld extends App println Hello World 文件另存为Hello sc
  • Scala 的代码覆盖率工具 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 模拟 BlazeClientBuilder[IO] 以返回模拟客户端[IO]

    我正在使用BlazeClientBuilder IO resource方法得到Client IO 现在 我想模拟客户端进行单元测试 但不知道该怎么做 有没有一个好的方法来嘲笑这个 我会怎么做 class ExternalCall val r
  • 使用 net.liftweb.json 或 scala.util.parsing.json 解析大型 (30MB) JSON 文件会出现 OutOfMemoryException。有什么建议吗?

    我有一个包含大量测试数据的 JSON 文件 我想解析这些数据并推送我正在测试的算法 它的大小约为 30MB 包含大约 60 000 个元素的列表 我最初在 scala util parsing json 中尝试了简单的解析器 如下所示 im
  • Spark:如何使用crossJoin

    我有两个数据框 df1有 100000 行并且df2有 10000 行 我想创建一个df3这是两者的交叉连接 val df3 df1 crossJoin df2 这将产生 10 亿行 尝试在本地运行它 但似乎需要很长时间 您认为本地可以实现
  • 方法返回类型前的 是什么意思?

    下面的方法返回一个List组成T类型元素 public
  • 理解 Scala FP 库

    只是为了让那些想要开始使用 Scala FP 库 在纯 FP 方面变得更好的人快速清晰地了解 有人能澄清猫和猫效应 猫效应 IO 之间的区别 关系吗 最重要的是 齐奥和莫尼克斯对此有何看法 最后 与 ScalaZ 7 8 有何关系 到目前为
  • 如何在映射中将字符串转换为 Seq[String]

    我有一个Map String String 以及需要的第三方功能Map String Seq String 有没有一种简单的方法来转换它 以便我可以将地图传递给函数 original mapValues Seq 注意mapValues返回地
  • Scala中有类似Java Stream的“peek”操作吗?

    在Java中你可以调用peek x gt println x 在 Stream 上 它将对每个元素执行操作并返回原始流 这与 foreach 不同 foreach 是 Unit Scala 中是否有类似的东西 最好是适用于所有 Monady
  • 在 Scala 中将元素追加到列表末尾

    我无法添加 type 元素T到一个列表中List T 我尝试过myList myElement但它似乎创建了一个奇怪的对象并访问myList last始终返回放入列表中的第一个元素 我怎么解决这个问题 List 1 2 3 4 Result
  • Java 8 Stream,获取头部和尾部

    Java 8 引入了Stream http download java net jdk8 docs api java util stream Stream html类似于 Scala 的类Stream http www scala lang
  • 如何在超时的情况下在单独的调度程序上运行 Akka Streams 图?

    这个问题是基于我做过的一个宠物项目 这个SO https stackoverflow com questions 34641861 akka http blocking in a future blocks the server 34645
  • 应对失败的“未来”

    给出以下两种方法 def f Future Int Future 10 def g Future Int Future 5 我想把它们写成 scala gt import scala concurrent Future import sca
  • 为什么自类型类可以声明类

    我知道 Scala 只能混合特征 这对于依赖注入和蛋糕模式是有意义的 我的问题是为什么我仍然可以声明一个需要另一个 类 但不需要特征的类 Code class C class D self C gt 这仍然编译成功 我认为它应该编译失败 因
  • Scala 案例类忽略 Spark shell 中的导入

    我希望这个问题有一个明显的答案 我刚刚升级到 Spark v2 0 并且遇到了一个奇怪的问题火花外壳 Scala 2 11 版本 如果我输入以下最小的 Scala import java sql Timestamp case class C
  • 返回 Java 8 中的通用函数接口

    我想写一种函数工厂 它应该是一个函数 以不同的策略作为参数调用一次 它应该返回一个函数 该函数根据参数选择其中一种策略 该参数将由谓词实现 嗯 最好看看condition3为了更好的理解 问题是 它没有编译 我认为因为编译器无法弄清楚函数式
  • Scala 和 Python 的通行证

    我想知道 是否有相当于 python 的 pass 表达式 这个想法是编写没有实现的方法签名 并编译它们只是为了对某些库原型的这些签名进行类型检查 我能够使用以下方法模拟这种行为 def pass A A throw new Excepti
  • 在spark-kafka中使用schema将ConsumerRecord值转换为Dataframe

    我正在使用 Spark 2 0 2 和 Kafka 0 11 0 并且 我正在尝试在火花流中使用来自卡夫卡的消息 以下是代码 val topics notes val kafkaParams Map String Object bootst

随机推荐

  • 如何序列化 Jackson 的 JsonNode 对象?

    我正在用 memcached 替换内部缓存系统 但 memcached 客户端无法缓存JsonNode对象 因为它们没有实现Serializable 有什么方法可以实现序列化JsonNode目的 杰克逊提供吗Serializable相当于这
  • python中,按日期字段排序,字段有时可能为null

    我很难想出一个巧妙的方法来处理这种情况 我有从数据库读取回来的数据 我想按会计日期排序 然而 accoutingdate 有时可能为空 我目前正在做以下事情 results sorted results key operator itemg
  • Rails - 禁用选择中的选项(根据条件)

    我已经选择 f select category id categories html options gt class gt select box disabled gt true if category id 18 上面的代码显然返回一个
  • Highcharts 反转折线图在最小值处部分隐藏

    当使用具有最小值和最大值的反向折线图时 线条在最小值处部分隐藏 问题在于绘图画布恰好在最小值线处结束 当一条粗线只有一部分可见时 位于最小值线上方的部分将被隐藏 你可以看一个例子here http jsfiddle net DruGa 2
  • 等待进程组时 waitpid() 无子进程错误

    编写我自己的玩具外壳 并在尝试实现作业控制时遇到了障碍 我正在使用 setpgid 在子进程和父进程中设置子进程组 我的等待电话是 pid waitpid pid status 0 然而 waitpid 返回 1 并且 perror 说 没
  • 从 unicode 字符串中去除特殊字符和标点符号

    我正在尝试从 unicode 字符串中删除标点符号 该字符串可能包含非 ASCII 字母 我尝试使用regex module import regex text u lt ik gt regex sub ur p P text 然而 我注意
  • Julia DataFrames 中的高效自定义排序?

    有没有一种快速的方法来指定自定义订单sort sort 在 Julia 数据框架上 julia gt using DataFrames julia gt srand 1 julia gt df DataFrame x rand 10 y r
  • WS02 ESB 中的 HL7 传输安全吗?

    我的小组正在评估 HL7 代理并遇到了 WS02 ESB 我已经成功配置了一个看起来运行良好的 HL7 代理 现在我的任务是使用 SSL 特别是 TLS 保护监听点 这似乎是 ESB 应该能够处理的事情 它可以执行 HTTPS 安全 Web
  • EditText android:提示不会在焦点上消失

    我使用的是 Android 4 我正在尝试向我的编辑文本小部件添加提示 我尝试将提示添加到布局中 如下所示
  • Bootstrap 4 - 垂直居中列表项

    我有一个使用 Bootstrap 4 beta 的网页 在此页面中 我有一个内联列表 我希望每个列表项的内容垂直居中 以便项目对齐 如图所示Bootply https www bootply com od2qnkLIkQ 它们目前偏离中心
  • Heroku:错误 R10(启动超时)-> Web 进程无法在启动后 60 秒内绑定到 $PORT - Python

    我正在尝试托管一个使用张量流到heroku的瓶子应用程序 应用程序启动 我得到了 服务器在端口上运行 以及 但应用程序未打开 大约一分钟后 它显示以下跟踪 打开跟踪表明服务器运行成功 2018 08 25T19 46 55 651043 0
  • Symfony 内存问题

    我在 symfony 和 cpu 内存泄漏方面遇到了困难 我是 symfony 的新手 我不知道我是否弄乱了任何技巧或技术来克服这个问题 我在 vps 上托管我当前的 symfony 项目 它几乎每隔一小时就会停止一次 我也想知道这些问题的
  • 如何在jquery中将html2canvas图像保存到系统文件夹中

    我有一个 id form1 的表单 在这个表单中我有一个图表 现在我使用 html2canvas 来获取此 form1 的图像 这是我的代码
  • 带有图标相对路径的 Windows 快捷方式

    有没有办法设置Windows快捷方式中图标的相对路径 对于目标位置 它工作正常 windir system32 cmd exe c cd CD start fileToExecute bat 我读到 win 快捷方式可以自动从 exe 文件
  • Android JavaCV 困境,创建 IplImage 时在“draw”方法中抛出 NoClassDefFoundError

    我正在使用 JavaCV 库和针对 Android 的预构建 OpenCV 库 我认为我已经以正确的方式设置了 Eclipse 因为我已经包含了 javacv jar 和 javacpp jar 两个 jar 另外 java cv andr
  • 如何将项目添加到SqlDataSource数据绑定列表

    我很懒 我正在使用 SQLDataSource 来填充我的下拉列表 数据绑定对象的 Databind 事件在 Page PreRender 之前调用 因此我在 PreRender 事件处理程序中执行类似的操作 private void In
  • assertThat - hamcrest - 检查列表是否已排序

    好吧 我认为这将是一个简短的问题 我有一个按日期排序的 ArrayList 当然我看到它有效 但我也想为它编写一个测试 我想检查列表中的下一个值 日期 是否低于前一个值 我可以使用一些来做到这一点fors 并添加临时列表 但我想知道是否有更
  • 如何使用 WiX 安装和启动 Windows 服务

    我尝试在 Wix 中使用下面的代码 但是在安装时 安装程 序在 正在启动服务 状态下冻结了大约 3 分钟 然后我收到此消息 Service Jobservice 无法启动 请验证您是否有足够的权限来启动系统服务 我的代码有什么错误吗 并且可
  • Gradle:将多个项目打包到一个jar中

    我有一个 gradle 多项目 想要创建一个包含子项目和外部依赖项的所有类的单个 jar 库 我有以下项目结构 每个项目都有自己的第 3 方依赖项 常见的依赖项包含在根项目中 两个模块A和B都依赖于核心 root project only
  • Scala:计算标准差的通用方法是什么

    我很好奇如何编写一个通用方法来计算 scala 中的标准差和方差 我有一个计算平均值的通用方法 从这里窃取 在 Scala 中编写通用均值函数 https stackoverflow com questions 6188990 writin