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:计算标准差的通用方法是什么 的相关文章

  • 自定义 NIO 文件系统无法通过 SBT 的测试任务加载

    为了进行测试 我使用内存中的 NIOFileSystem执行 memoryfs https github com openCage memoryfs 我以前已经利用过它 并且它似乎运行良好 例如梅文 然而 现在 在SBT项目中 不可能初始化
  • 新式(“内联”)宏需要 scala.meta

    我刚刚更新到 scala meta 2 0 0 M1 和最新的 scala 2 12 3 现在宏不再编译 我所做的唯一更改是将元版本从 1 8 0 更改为 2 0 0 M1 错误 新式 内联 宏需要 scala meta 有谁知道是否有快速
  • Scala:具有复杂结构的树插入尾递归

    我正在 scala 中创建自定义对象树 并且我的插入方法引发堆栈溢出 因为它不是尾递归 但是 我不太清楚如何使其尾递归 我见过使用 累加器 变量的相关示例 但它们要么是只能相乘和覆盖的整数之类的东西 要么是我在适应树时遇到困难的列表 这是我
  • Swift:覆盖子类内的类型别名

    所以我正在考虑在我的项目中使用自定义模式 但我无法让它发挥作用 主要思想是改变typealias在每个子类上访问子类特定的接口 protocol InstanceInterface class typealias Interface var
  • 了解 Scala 中的中缀方法调用和缺点运算符(::)

    我对 Scala 编程语言相当陌生 当我遵循以下网站的讲义时 我正在尝试一些萦绕在我脑海中的东西 here http horstmann com sjsu cs152 04 closures1 html 我想我无法真正理解 cons 运算符
  • 有没有办法捕获 Spark 中使用通配符读取的多个 parquet 文件的输入文件名?

    我使用 Spark 将多个 parquet 文件读取到单个 RDD 中 并使用标准通配符路径约定 换句话说 我正在做这样的事情 val myRdd spark read parquet s3 my bucket my folder parq
  • 使用 Spray-json 解析简单数组

    我正在尝试 但失败了 了解 Spray json 如何将 json feed 转换为对象 如果我有一个简单的 key gt value json feed 那么它似乎可以正常工作 但是我想要读取的数据出现在如下列表中 name John a
  • 如何捕获 Oozie Spark 输出

    有没有办法捕获spark的输出然后将其输入到shell上 我们当前正在使用 scala 创建 jar 文件 并希望我们的 Spark 输出成为 shell 输入 我的想法是使用 wf actionData spark XXXX var 我只
  • 为什么不自动装箱泛型的 Java 基本类型?

    Java 不允许在通用数据结构中使用原始类型 例如 不允许使用 ArrayList 原因是 原始类型不能直接转换为Object 然而 Java 1 5 确实支持自动装箱 并且包装类在通用数据结构中工作 那么为什么编译器不能将其自动装箱到 A
  • 在 Spring xml 配置中创建 Guava TypeToken?

    我希望能够注射Guava 类型令牌 http docs guava libraries googlecode com git javadoc com google common reflect TypeToken html对象通过在 Spr
  • Play Framework 2.3 (Scala) 中的自定义 JSON 验证约束

    我设法使用自定义约束实现表单验证 但现在我想对 JSON 数据执行相同的操作 如何将自定义验证规则应用于 JSON 解析器 示例 客户端的 POST 请求包含用户名 username 我不仅要确保该参数是非空文本 而且还要确保该用户确实存在
  • Scala 和变量中的模式匹配

    我是 Scala 新手 有点想知道模式匹配是如何工作的 想象一下我有以下内容 case class Cls i Int case b Cls i gt Ok case e Cls gt Ok case f Cls gt Ok case s
  • 关于 ArrayList[] x 的 Java 问题

    我一直对 ArrayList 数组有这个问题 也许你能帮忙 declare in class private ArrayList
  • Spark Scala 将列从一个数据帧复制到另一个数据帧

    我有一个原始数据框的修改版本 我在其上进行了聚类 现在我想将预测列恢复为原始 DF 索引没问题 因此匹配 我该怎么做 使用这段代码我得到一个错误 println Predicted dfWithOutput show println Ori
  • 这种复杂的泛型模式会导致 Eclipse 崩溃 - 我可以让它工作吗?

    我使用的是 Eclipse Luna 4 4 0 JDK 1 8 0 05 我正在制作一个游戏 游戏世界的拓扑结构可以大致分为World gt Level gt Tile 其中图块是地形的一个小单位 我设置了三个项目 一个包含这些结构的一些
  • 缓存 Slick DBIO 操作

    我正在尝试加快 SELECT FROM WHERE name 的速度Play 中的查询类型 Scala 应用程序 我正在使用 Play 2 4 Scala 2 11 play slick 1 1 1 包 该软件包使用Slick 3 1版本
  • 类型级编程有哪些示例? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我不明白 类型级编程 是什么意思 也无法使用Google找到合适的解释 有人可以提供一个演示类型级编程的示例吗 范式的解释和 或定义将
  • TObjectList.Contains 导致 Delphi 2009 中的访问冲突

    在 Delphi 2009 中 到目前为止 我在泛型方面没有遇到大问题 使用 Generics Collections 列表 没有特殊的泛型功能 现在我发现这段代码会在访问的行中导致AVMyList Contains 如果我声明 TMyLi
  • Scala 解析器组合器的运算符优先级

    我正在研究需要考虑运算符优先级的解析逻辑 我的需求并不太复杂 首先 我需要乘法和除法比加法和减法具有更高的优先级 例如 1 2 3 应视为 1 2 3 这是一个简单的例子 但你明白了 我需要将更多自定义标记添加到优先级逻辑中 我可以根据此处
  • 在 Scala 中,使用“_”和使用命名标识符有什么区别?

    为什么当我尝试使用时会出现错误 而不是使用命名标识符 scala gt res0 res25 List Int List 1 2 3 4 5 scala gt res0 map gt item toString

随机推荐

  • 如何序列化 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