返回介绍

solution / 0500-0599 / 0550.Game Play Analysis IV / README

发布于 2024-06-17 01:03:59 字数 3256 浏览 0 评论 0 收藏 0

550. 游戏玩法分析 IV

English Version

题目描述

Table: Activity

+--------------+---------+
| Column Name  | Type  |
+--------------+---------+
| player_id  | int   |
| device_id  | int   |
| event_date   | date  |
| games_played | int   |
+--------------+---------+
(player_id,event_date)是此表的主键(具有唯一值的列的组合)。
这张表显示了某些游戏的玩家的活动情况。
每一行是一个玩家的记录,他在某一天使用某个设备注销之前登录并玩了很多游戏(可能是 0)。

 

编写解决方案,报告在首次登录的第二天再次登录的玩家的 比率四舍五入到小数点后两位。换句话说,你需要计算从首次登录日期开始至少连续两天登录的玩家的数量,然后除以玩家总数。

结果格式如下所示:

 

示例 1:

输入:
Activity table:
+-----------+-----------+------------+--------------+
| player_id | device_id | event_date | games_played |
+-----------+-----------+------------+--------------+
| 1     | 2     | 2016-03-01 | 5      |
| 1     | 2     | 2016-03-02 | 6      |
| 2     | 3     | 2017-06-25 | 1      |
| 3     | 1     | 2016-03-02 | 0      |
| 3     | 4     | 2018-07-03 | 5      |
+-----------+-----------+------------+--------------+
输出:
+-----------+
| fraction  |
+-----------+
| 0.33    |
+-----------+
解释:
只有 ID 为 1 的玩家在第一天登录后才重新登录,所以答案是 1/3 = 0.33

解法

方法一:分组取最小值 + 左连接

我们可以先找到每个玩家的首次登录日期,然后与原表进行左连接,连接条件为玩家 ID 相同且日期差为 $-1$,即第二天登录。那么,我们只需要统计出第二天登录的玩家数量中,玩家不为空的比率即可。

import pandas as pd


def gameplay_analysis(activity: pd.DataFrame) -> pd.DataFrame:
  activity["first"] = activity.groupby("player_id").event_date.transform(min)
  activity_2nd_day = activity[
    activity["first"] + pd.DateOffset(1) == activity["event_date"]
  ]

  return pd.DataFrame(
    {"fraction": [round(len(activity_2nd_day) / activity.player_id.nunique(), 2)]}
  )
# Write your MySQL query statement below
SELECT ROUND(AVG(b.event_date IS NOT NULL), 2) AS fraction
FROM
  (
    SELECT player_id, MIN(event_date) AS event_date
    FROM Activity
    GROUP BY 1
  ) AS a
  LEFT JOIN Activity AS b
    ON a.player_id = b.player_id AND DATEDIFF(a.event_date, b.event_date) = -1;

方法二:窗口函数

我们也可以使用窗口函数 LEAD 获取每个玩家的下一次登录日期,如果下一次登录日期与当前登录日期相差 $1$ 天,则说明该玩家在第二天登录,我们用一个字段 $st$ 记录该信息。然后,我们用窗口函数 RANK 对玩家 ID 按照日期升序排列,得到每个玩家的登录排名。最后,我们只需要统计出排名为 $1$ 的玩家中,字段 $st$ 不为空的比率即可。

# Write your MySQL query statement below
WITH
  T AS (
    SELECT
      player_id,
      DATEDIFF(
        LEAD(event_date) OVER (
          PARTITION BY player_id
          ORDER BY event_date
        ),
        event_date
      ) = 1 AS st,
      RANK() OVER (
        PARTITION BY player_id
        ORDER BY event_date
      ) AS rk
    FROM Activity
  )
SELECT ROUND(COUNT(IF(st = 1, player_id, NULL)) / COUNT(DISTINCT player_id), 2) AS fraction
FROM T
WHERE rk = 1;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文