Как рассчитать скользящую статистику в Scala - PullRequest
0 голосов
/ 23 сентября 2018

У меня есть знания по обработке Dataframes в Python, но я сталкиваюсь с приведенной ниже проблемой при написании в scala.

case class Transaction(
      transactionId: String,
      accountId: String,
      transactionDay: Int,
      category: String,
      transactionAmount: Double)

Я создал такой список:

  val transactions: List[Transaction] = transactionslines.map {           
      line => val split = line.split(',')
      Transaction(split(0), split(1), split(2).toInt, split(3),split(4).toDouble)
      }.toList

Содержание списка:

  Transaction(T000942,A38,28,EE,694.54)
  Transaction(T000943,A35,28,CC,828.57)
  Transaction(T000944,A26,28,DD,290.18)
  Transaction(T000945,A17,28,CC,627.62)
  Transaction(T000946,A42,28,FF,616.73)
  Transaction(T000947,A20,28,FF,86.84)
  Transaction(T000948,A14,28,BB,620.32)
  Transaction(T000949,A14,28,AA,260.02)
  Transaction(T000950,A32,28,AA,600.34)

Может ли кто-нибудь помочь мне с тем, как рассчитать статистику для каждого номера счета за предыдущие пять дней транзакций, не считая транзакций за день, для которого рассчитывается статистика.Например, на 10-й день вы должны рассматривать только транзакции с 5-го по 9-й (это называется скользящим временным окном в пять дней).Мне нужно рассчитать следующие статистические данные:

• Общая стоимость транзакции типа транзакции «AA» за предыдущие 5 дней для одного аккаунта

• Средняя стоимость транзакции за предыдущие 5 дней транзакцийна счет

В идеале выходные данные должны содержать одну строку в день для идентификатора счета, а каждая строка должна содержать каждую из рассчитанных статистических данных:

Мой код за первые 5 дней выглядит следующим образом:

val a = transactions.
        filter(trans => trans.transactionDay <= 5).
        groupBy(_.accountId).
        mapValues(trans => (trans.map(amount => 
        amount.transactionAmount).sum/trans.map(amount => 
        amount.transactionAmount).size,trans.filter(trans => 
        trans.category == "AA").map(amount => 
        amount.transactionAmount).sum)
a.foreach{println}

Я хотел бы знать, есть ли какой-нибудь элегантный способ вычислить эту статистику.Обратите внимание, что день трансакции варьируется от [1..29], поэтому в идеале мне нужен код, который рассчитывает эти скользящие статистические данные до 29-го дня, а не только для первых 5 дней.

Большое спасибо !!

1 Ответ

0 голосов
/ 24 сентября 2018

Возможно, не «элегантный», но следующие данные предоставят две желаемые статистические данные accountID за конкретный день:

def calcStats(ts: List[Transaction], day: Int): Map[String, (Double, Double)] = {
  // all transactions for date range, grouped by accountID
  val atsById = ts
   .filter(trans => trans.transactionDay >= day - 5 && trans.transactionDay < day)
   .groupBy(_.accountId)
  // "AA" transactions summmed by account id
  val aaSums = atsById.mapValues(_.filter(_.category == "AA"))
                      .mapValues(_.map(_.transactionAmount).sum)
  // sum of all transactions by account id
  val allSums = atsById.mapValues(_.map(_.transactionAmount).sum)
  // count of all transactions by account id
  val allCounts = atsById.mapValues(_.length)
  // output is Map(account id -> (aaSum, allAve))
  allSums.map { case (id, sum) => 
    id -> (aaSums.getOrElse(id, 0.0), sum / allCounts(id)) }
}

примеров (используя предоставленные вами данные):

scala> calcStats(transactions, 30)
res13: Map[String,(Double, Double)] = Map(A32 -> (600.34,600.34), A26 -> 
(0.0,290.18), A38 -> (0.0,694.54), A20 -> (0.0,86.84), A17 -> (0.0,627.62), 
A42 -> (0.0,616.73), A35 -> (0.0,828.57), A14 -> (260.02,440.17))

scala> calcStats(transactions, 1)
res14: Map[String,(Double, Double)] = Map()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...