Valoracion de pelicula

Escribe una solución para: - Encontrar el nombre del usuario quien ha valorado más películas. En caso de empate, regresa el nombre de usuario lexicograficamente menor. - Encuentra la película con la valoración promedia más alta en Febrero de 2020. En caso de empate, regresa la película lexicograficamente menor.

#pandas#subqueries

Tabla: Movies

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| movie_id      | int     |
| title         | varchar |
+---------------+---------+

- movie_id es la llave primaria (columna con valores únicos).
- title es el nombre de la película.

Tabla: Users

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| user_id       | int     |
| name          | varchar |
+---------------+---------+

- user_id es la llave primaria (columna con valores únicos).

Tabla: MovieRating

+---------------+---------+
| Column Name   | Type    |
+---------------+---------+
| movie_id      | int     |
| user_id       | int     |
| rating        | int     |
| created_at    | date    |
+---------------+---------+

- (movie_id, user_id) es la llave primaria (columna con valores únicos).
- Esta tabla contine la valoración de una película por cada usuario.
- created_at es la fecha de valoración de la película.

El formato del resultado se muestra en el siguiente ejemplo.

Ejemplo 1:

Entrada:

Tabla Movies:
+-------------+--------------+
| movie_id    |  title       |
+-------------+--------------+
| 1           | Avengers     |
| 2           | Frozen 2     |
| 3           | Joker        |
+-------------+--------------+

Tabla Users:
+-------------+--------------+
| user_id     |  name        |
+-------------+--------------+
| 1           | Daniel       |
| 2           | Monica       |
| 3           | Maria        |
| 4           | James        |
+-------------+--------------+

Tabla MovieRating:
+----------+---------+--------+------------+
| movie_id | user_id | rating | created_at |
+----------+---------+--------+------------+
| 1        | 1       | 3      | 2020-01-12 |
| 1        | 2       | 4      | 2020-02-11 |
| 1        | 3       | 2      | 2020-02-12 |
| 1        | 4       | 1      | 2020-01-01 |
| 2        | 1       | 5      | 2020-02-17 |
| 2        | 2       | 2      | 2020-02-01 |
| 2        | 3       | 2      | 2020-03-01 |
| 3        | 1       | 3      | 2020-02-22 |
| 3        | 2       | 4      | 2020-02-25 |
+----------+---------+--------+------------+

Salida:

+--------------+
| results      |
+--------------+
| Daniel       |
| Frozen 2     |
+--------------+

Explicación:
- Daniel y Monica han valorado 3 películas ('Avengers', 'Frozen 2' y 'Joker') pero Daniel viene antes que Monica lexicograficamente hablando.
- Frozen 2 y Joker han un promedio de valoración de 3.5 en Febrero pero Frozen 2 viene antes lexicograficamente.

Solución:

import pandas as pd


def movie_rating(
    movies: pd.DataFrame,
    users: pd.DataFrame,
    movie_rating: pd.DataFrame
) -> pd.DataFrame:
    # Filter user
    rating_cnts = movie_rating.groupby('user_id')['rating'].count().reset_index(name='rating_cnt')
    df = pd.merge(users, rating_cnts).sort_values('name')
    max_rating = rating_cnts.rating_cnt.max()
    user = df[df.rating_cnt.eq(max_rating)].head(1)

    # Filter movie
    movie_rating['month'] = movie_rating['created_at'].dt.strftime('%Y-%m')

    feb_df = movie_rating[movie_rating['month'].eq('2020-02')]
    feb_df = feb_df.groupby('movie_id')['rating'].mean().reset_index(name='rating_avg')
    feb_df = feb_df.merge(movies).sort_values('title')

    max_rating_avg = feb_df.rating_avg.max()
    movie = feb_df[feb_df.rating_avg.eq(max_rating_avg)].head(1)

    username = user['name'].tolist()[0]
    movietitle = movie['title'].tolist()[0]

    return pd.DataFrame({'results': [username, movietitle]})


def test_movie_rating():
    data = [[1, 'Avengers'], [2, 'Frozen 2'], [3, 'Joker']]
    movies = pd.DataFrame(
        data,
        columns=['movie_id', 'title']
    ).astype({'movie_id':'Int64', 'title':'object'})
    data = [[1, 'Daniel'], [2, 'Monica'], [3, 'Maria'], [4, 'James']]
    users = pd.DataFrame(
        data,
        columns=['user_id', 'name']
    ).astype({'user_id':'Int64', 'name':'object'})
    data = [
        [1, 1, 3, '2020-01-12'],
        [1, 2, 4, '2020-02-11'],
        [1, 3, 2, '2020-02-12'],
        [1, 4, 1, '2020-01-01'],
        [2, 1, 5, '2020-02-17'],
        [2, 2, 2, '2020-02-01'],
        [2, 3, 2, '2020-03-01'],
        [3, 1, 3, '2020-02-22'],
        [3, 2, 4, '2020-02-25']
    ]
    _movie_rating = pd.DataFrame(
        data, columns=['movie_id', 'user_id', 'rating', 'created_at']
    ).astype({
        'movie_id': 'Int64',
        'user_id': 'Int64',
        'rating': 'Int64',
        'created_at':'datetime64[ns]'
    })

    expected = pd.DataFrame(
        [['Daniel'], ['Frozen 2']],
        columns=['results']).astype({'results': str})

    got = movie_rating(movies, users, _movie_rating)
    pd.testing.assert_frame_equal(got, expected)

slackmart blog © 2024