Самый идиоматический способ получить гистограмму значений в коллекции Scala - это использовать groupBy
, а затем карту, которая принимает размер каждой результирующей группы:
scala> import collection.mutable.ListBuffer
import collection.mutable.ListBuffer
scala> val values = ListBuffer(1, 1, 0, 1, 0, 1, 1, 1, 1)
values: scala.collection.mutable.ListBuffer[Int] = ListBuffer(1, 1, 0, 1, 0, 1, 1, 1, 1)
scala> values.groupBy(identity).mapValues(_.size)
res0: scala.collection.immutable.Map[Int,Int] = Map(1 -> 7, 0 -> 2)
В вашем случае эта часть полностью независим от части Spark - вы просто выполняете эту операцию со значениями в СДР, но полное решение будет выглядеть так:
scala> val counts = myRdd.mapValues(_.groupBy(identity).mapValues(_.size))
counts: org.apache.spark.rdd.RDD[(Int, scala.collection.immutable.Map[Int,Int])] = MapPartitionsRDD[1] at mapValues at <console>:26
scala> counts.foreach(println)
(1000,Map(1 -> 2))
(21010,Map(0 -> 3))
(23000,Map(1 -> 5))
(34000,Map(0 -> 1))
(31000,Map(1 -> 7, 0 -> 2))
Стоит отметить, что mapValues
в Scala Коллекции ленивы, что означает, что каждый раз, когда вы используете карты в СДР, значения будут пересчитываться. Это, вероятно, хорошо, но если вас это беспокоит, вы можете заменить его на что-то вроде этого:
values.groupBy(identity).map { case (k, v) => k -> v.size }
... что вернет строго оцененную карту.
Если ваш статус это значение, которое изменяется, вы должны разбить его на две отдельные части.
Обновление статуса. Это должно быть вызвано в функции представления. Настоящая работа, однако, принадлежит модели. Функция просмотра вызывает метод модели и выполняет сохранение.
Отображение статуса. Это просто некоторое строковое представление статуса.
Модель
class MyStatefulModel( models.Model ):
theState = models.CharField( max_length=64 )
def changeState( self ):
if theState is None:
theState= "viewed"
elif theState is "viewed":
theState= "learning"
etc.
Функция представления
def show( request, object_id ):
object= MyStatefulModel.objects.get( id=object_id )
object.changeState()
object.save()
render_to_response( ... )
Шаблон
<p>Your status is {{object.theState}}.</p>
Да, вы можете добавить метод к вашей модели с параметром запроса:
class MyModel(models.Model):
fields....
def update_status(self, request):
make something with the request...