【问题标题】:Find simple frequency pattern in dates在日期中查找简单的频率模式
【发布时间】:2018-03-14 09:41:54
【问题描述】:

我有一份客户付款日期列表,我正在查看付款是否有 7/14 天或每月的模式,通常有!。问题是也可能有类似价值的中间付款,因此仅查看付款之间的时间并不总是有效。 是否有任何简单的方法(使用 SQL 或 R)可以帮助我将客户分类为按周付款或按月付款?

似乎是一个非常简单的信号处理问题,但也许我不知道谷歌的正确词,因为我找不到任何东西。任何指出我正确方向的人将不胜感激!

示例数据:

    CustomerID  Payment Date
    Customer1   2017-01-05
    Customer1   2017-01-06
    Customer1   2017-01-12
    Customer1   2017-01-17
    Customer1   2017-01-19
    Customer1   2017-01-19
    Customer1   2017-01-26
    Customer1   2017-02-02
    Customer1   2017-02-03
    Customer2   2017-06-04
    Customer2   2017-06-06
    Customer2   2017-07-04
    Customer2   2017-07-06
    Customer2   2017-07-22
    Customer2   2017-07-28
    Customer2   2017-08-06

示例输出

    CustomerID   Classification   
    Customer1    Weekly
    Customer2    Monthly

编辑:为了清楚起见,数据通常比上面要大得多,而且噪音更大。我只是在寻找寻找模式的算法的一般思路,而不是尝试解决我发布的小数据集的问题。

【问题讨论】:

  • 乍一看,每月付款的最大天数差异为 28,而每周最多不超过 7...
  • 我的方法(如果使用 postgres 或 redshift)是创建一个 python UDF 函数并为每个客户调用它,将该客户的付款日期的完整列表传递给 python。 python 代码将使用一些模糊逻辑来识别最佳模式并仅返回字符串“monthly”、“fortnightly”或“weekly”。
  • @Sotos,很好的观察,我实际上已经让数据比它更简单一些,所以它不会总是坚持下去,但它让我思考。感谢 Jon,但目前不使用 Python。
  • 您如何将Customer2 视为每月一次。据我所知,他访问了06-0406-06。不应该每周考虑他吗?我认为如果一个人在7 天内访问不止一次,他将被视为weekly。如果他在> 7 天和< 28 天访问不止一次,他将被视为每月一次。还是我理解不正确?或者您的逻辑是,如果客户仅访问June,他将被视为weekly,如果他访问JuneJuly,他将被视为monthly

标签: sql r teradata frequency


【解决方案1】:
payment_date <-
  as.Date(
    c(
      "2017-01-05",
      "2017-01-06",
      "2017-01-12",
      "2017-01-17",
      "2017-01-19",
      "2017-01-19",
      "2017-01-26",
      "2017-02-02",
      "2017-02-03",
      "2017-06-04",
      "2017-06-06",
      "2017-07-04",
      "2017-07-06",
      "2017-07-22",
      "2017-07-28",
      "2017-08-06"
    )
  )

df <- data.frame(payment_date,
                 customer_id = 0)

df$customer_id[1:9] <- 1
df$customer_id[10:16] <- 2

customer_information <- data.frame(customer_id = numeric(),
                                   payment = character())

for (i in 1:length(unique(df$customer_id))) {
  delta_t <-
    abs(as.numeric(df$payment_date[(df$customer_id == i) &
                                     (!duplicated(df$customer_id))] - df$payment_date[(df$customer_id == i) &
                                                                                        (!duplicated(df$customer_id, fromLast = TRUE))]))
  nr_of_payments <- NROW(df[df$customer_id == i,])
  days_to_pay <- delta_t / nr_of_payments

  if (days_to_pay > 7) {
    to_add <- data.frame(customer_id = i,
                         payment = "monthly")
    customer_information <- rbind(customer_information, to_add)
  } else{
    to_add <- data.frame(customer_id = i,
                         payment = "weekly")
    customer_information <- rbind(customer_information, to_add)
  }
}

代码使用客户支付的平均时间。如果平均时间超过 7,他是按月付款,否则他是按周付款。

它有效,但我想这不是一个令人满意的解决方案。似乎每月/每周有两次付款。如果是这种情况,您可以考虑获得更准确的结果。

【讨论】:

    猜你喜欢
    • 2023-03-20
    • 2020-11-23
    • 1970-01-01
    • 2013-10-05
    • 2014-09-10
    • 1970-01-01
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    相关资源
    最近更新 更多