Quiero al azar de la muestra a partir de una Scala lista o matriz (no un RDD), el tamaño de la muestra puede ser mucho más largo que la longitud de la lista o matriz, ¿cómo puedo hacer esto de manera eficiente? Debido a que el tamaño de la muestra puede ser muy grande y la toma de muestras (en diferentes listas o matrices) se necesita hacer un gran número de veces.

Sé que es una Chispa RDD podemos utilizar takeSample() para hacerlo, hay un equivalente para Scala, lista o matriz?

Muchas gracias.

Generadores de números aleatorios son el estado, por lo que no tiene sentido, las Listas tienen una función de este tipo. Usted tendría que poner en práctica uno mismo (también, sería un tiempo lineal de la operación). Para las matrices, usted puede obtener un número entero aleatorio comprendido desde el «Azar» de los objetos así: ‘al Azar.nextInt(myArray.de longitud)’ y el índice en la matriz.
Ahh, nvm. He leído demasiado rápido xD
Gracias Felix por tu ayuda.

OriginalEl autor Carter | 2015-10-04

7 Comentarios

  1. 24

    Un fácil-a-entender versión tendría este aspecto:

    import scala.util.Random
    
    Random.shuffle(list).take(n)
    Random.shuffle(array.toList).take(n)
    
    //Seeded version
    val r = new Random(seed)
    r.shuffle(...)
    «el tamaño de la muestra puede ser más largo que la longitud de la lista o matriz,»
    Te comento antes de probar el código, derecho?
    Yo sé cómo tomar funciona, pero no creo que él significa que también debe dar una muestra más grande que la secuencia en que caso?
    Si él quiere con reemplazo, a continuación, usted está en lo correcto.
    Gracias chicos. Sí necesito muestreo con reemplazo y el tamaño de la muestra es siempre mucho mayor que la longitud de la matriz/lista de, por ejemplo, es posible que necesite a 10.000 muestras de una lista de 50 longitud.

    OriginalEl autor Marius Soutier

  2. 3

    Para las matrices:

    import scala.util.Random
    import scala.reflect.ClassTag
    
    def takeSample[T:ClassTag](a:Array[T],n:Int,seed:Long) = {
      val rnd = new Random(seed)
      Array.fill(n)(a(rnd.nextInt(a.size)))
    }

    Hacer un generador de números aleatorios (rnd) basado en su semilla. A continuación, rellenar una matriz con números aleatorios de 0 hasta el tamaño de la matriz.

    El último paso es la aplicación de cada valor aleatorio a la indexación del operador de la matriz de entrada. Su uso en el REPL podría ser como sigue:

    scala> val myArray = Array(1,3,5,7,8,9,10)
    myArray: Array[Int] = Array(1, 3, 5, 7, 8, 9, 10)
    
    scala> takeSample(myArray,20,System.currentTimeMillis)
    res0: scala.collection.mutable.ArraySeq[Int] = ArraySeq(7, 8, 7, 3, 8, 3, 9, 1, 7, 10, 7, 10,
    1, 1, 3, 1, 7, 1, 3, 7)

    Para las listas, yo simplemente convertir la lista de la Matriz y el uso de la misma función. Dudo que usted puede conseguir mucho más eficiente para las listas de todos modos.

    Es importante señalar, que la misma función utilizando listas sería O(n^2) el tiempo, mientras que la conversión de la lista a las matrices primera será O(n) tiempo

    Su takeSample método es innecesariamente la creación de la matriz que contiene los índices y, a continuación, la asignación de eso. Usted debe, probablemente, en lugar de hacer algo como Array.fill(n)(a(rng.nextInt(a.size)))
    Sí que no se compila sin embargo. Es incapaz de encontrar no requiere de manifiesto. Probablemente, usted sólo tiene que añadir el parámetro explícito y va a trabajar.
    He actualizado a trabajar como su idea 🙂
    Cuando ejecuto el código de arriba me sale el siguiente. ¿Qué estoy haciendo mal? scala> takeSample(myArray,20 de Sistema.currentTimeMillis) res0: Array[() => Int] = Array(<function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>, <function0>)
    Por favor, inténtelo de nuevo. He cambiado de () => a(rnd.nextInt(a.size)) a a(rnd.nextInt(a.size)) y se añade el classtag de T en el fin de la construcción de la matriz de trabajo. Pruébelo ahora 🙂 lo Siento por las molestias

    OriginalEl autor Felix

  3. 1

    Con una para la comprensión, para una matriz dada xs de la siguiente manera,

    for (i <- 1 to sampleSize; r = (Math.random * xs.size).toInt) yield a(r)

    Nota el generador de números aleatorios aquí produce valores dentro de la unidad de intervalo, que se reducen a la gama más el tamaño de la matriz, y se convierte a Int para la indexación sobre la matriz.

    Nota Por pura funcional generador de números aleatorios considerar, por ejemplo, el Estado de Mónada enfoque de Programación funcional en Scala, discutido aquí.

    Nota Considerar también NICTA, otro puro funcional aleatorio generador de valor, su uso se ilustra por ejemplo aquí.

    No es de Matemáticas.al azar mala práctica? Esto es, literalmente, estática estado global.
    en mi mente hay una enorme diferencia entre lo local y lo global. Uno es malo, el otro es horrible.

    OriginalEl autor elm

  4. 1

    Utilizando clásico de recursividad.

    import scala.util.Random
    
    def takeSample[T](a: List[T], n: Int): List[T] = {
        n match {
          case n: Int if n <= 0 => List.empty[T]
          case n: Int => a(Random.nextInt(a.size)) :: takeSample(a, n - 1)
        }
    }
    takeSample(List(1,2,3),10000) probar este, que va a explotar porque no cola-recursiva.

    OriginalEl autor thomas pocreau

  5. 1

    Si quieres degustar sin reemplazo-zip con randoms, ordenar O(n*log(n), descartar randoms, tomar

    import scala.util.Random
    val l = Seq("a", "b", "c", "d", "e")
    val ran = l.map(x => (Random.nextFloat(), x))
      .sortBy(_._1)
      .map(_._2)
      .take(3)

    OriginalEl autor KevinKatz

  6. 0
    package your.pkg
    
    import your.pkg.SeqHelpers.SampleOps
    
    import scala.collection.generic.CanBuildFrom
    import scala.collection.mutable
    import scala.language.{higherKinds, implicitConversions}
    import scala.util.Random
    
    trait SeqHelpers {
    
      implicit def withSampleOps[E, CC[_] <: Seq[_]](cc: CC[E]): SampleOps[E, CC] = SampleOps(cc)
    }
    
    object SeqHelpers extends SeqHelpers {
    
      case class SampleOps[E, CC[_] <: Seq[_]](cc: CC[_]) {
    
        private def recurse(n: Int, builder: mutable.Builder[E, CC[E]]): CC[E] = n match {
          case 0 => builder.result
          case _ =>
            val element = cc(Random.nextInt(cc.size)).asInstanceOf[E]
            recurse(n - 1, builder += element)
        }
    
        def sample(n: Int)(implicit cbf: CanBuildFrom[CC[_], E, CC[E]]): CC[E] = {
          require(n >= 0, "Cannot take less than 0 samples")
          recurse(n, cbf.apply)
        }
      }
    }

    :

    • Mixin SeqHelpers, por ejemplo, con un Scalatest spec
    • Incluyen import your.pkg.SeqHelpers._

    A continuación, los siguientes trabajos:

    Seq(1 to 100: _*) sample 10 foreach { println }

    Ediciones de quitar el yeso son bienvenidos.

    También si hay una manera de crear un vacío de la instancia de la colección para el acumulador, sin saber el tipo concreto antes de tiempo, por favor comente. Dicho esto, el generador es probablemente más eficiente.

    OriginalEl autor Darren Bishop

  7. 0

    No hizo las pruebas para el rendimiento, pero el código siguiente es un sencillo y elegante manera de hacer el muestreo y creo que puede ayudar a muchos que vienen aquí sólo para obtener un muestreo código. Acaba de cambiar el «rango» de acuerdo con el tamaño de tu muestra. Si pseude-aleatoriedad no es suficiente para sus necesidades, usted puede usar la toma(1) en el interior lista y aumentar la gama.

    Random.shuffle((1 to 100).toList.flatMap(x => (Random.shuffle(yourList))))

    OriginalEl autor ruhsuzbaykus

Dejar respuesta

Please enter your comment!
Please enter your name here